Also, introduce Vecs and FilterVecs classes. These are implemented as Meyers singeltons. This avoids some issues with initialization order.
All formats except gpx are used as LegacyFormats, which is deprecated. The gpx format has been converted to demonstrate the preferred usage.
defs.h
explorist_ini.h
filter.h
- filterdefs.h
+ filter_vecs.h
+ format.h
garmin_device_xml.h
garmin_fs.h
garmin_gpi.h
gbser.h
gbser_private.h
gbversion.h
+ gpx.h
grtcirc.h
heightgrid.h
holux.h
jeeps/gpsusbcommon.h
jeeps/gpsusbint.h
jeeps/gpsutil.h
+ legacyformat.h
magellan.h
mapsend.h
navilink.h
shapelib/shapefil.h
strptime.h
units.h
+ vecs.h
xcsv.h
xmlgeneric.h
zlib/crc32.h
defs.h \
explorist_ini.h \
filter.h \
- filterdefs.h \
+ filter_vecs.h \
+ format.h \
garmin_device_xml.h \
garmin_fs.h \
garmin_gpi.h \
gbser.h \
gbser_private.h \
gbversion.h \
+ gpx.h \
grtcirc.h \
heightgrid.h \
holux.h \
jeeps/gpsusbcommon.h \
jeeps/gpsusbint.h \
jeeps/gpsutil.h \
+ legacyformat.h \
magellan.h \
mapsend.h \
navilink.h \
shapelib/shapefil.h \
strptime.h \
units.h \
+ vecs.h \
xcsv.h \
xmlgeneric.h \
zlib/crc32.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h an1sym.h
arcdist.o: arcdist.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- arcdist.h filter.h filterdefs.h grtcirc.h
+ arcdist.h filter.h grtcirc.h src/core/logging.h
bcr.o: bcr.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h csv_util.h \
garmin_tables.h
bend.o: bend.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
- gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h bend.h grtcirc.h
+ gbfile.h session.h src/core/datetime.h src/core/optional.h bend.h \
+ filter.h grtcirc.h
brauniger_iq.o: brauniger_iq.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
cet.h inifile.h gbfile.h session.h src/core/datetime.h \
src/core/optional.h gbser.h
gbser.h
discard.o: discard.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- discard.h filter.h filterdefs.h
+ discard.h filter.h
dmtlog.o: dmtlog.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
jeeps/gpsmath.h jeeps/gpsport.h xmlgeneric.h
duplicate.o: duplicate.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h duplicate.h
+ duplicate.h filter.h
easygps.o: easygps.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
energympro.o: energympro.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
filter_vecs.o: filter_vecs.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
cet.h inifile.h gbfile.h session.h src/core/datetime.h \
- src/core/optional.h arcdist.h filter.h bend.h discard.h duplicate.h \
- filterdefs.h height.h interpolate.h nukedata.h polygon.h position.h \
+ src/core/optional.h filter_vecs.h arcdist.h filter.h bend.h discard.h \
+ duplicate.h height.h interpolate.h nukedata.h polygon.h position.h \
radius.h reverse_route.h smplrout.h sort.h stackfilter.h swapdata.h \
- trackfilter.h transform.h validate.h gbversion.h
+ trackfilter.h transform.h validate.h gbversion.h vecs.h format.h gpx.h \
+ src/core/file.h src/core/xmlstreamwriter.h src/core/xmltag.h \
+ legacyformat.h
formspec.o: formspec.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
g7towin.o: g7towin.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
garmin_tables.h strptime.h
garmin.o: garmin.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- cet_util.h garmin_device_xml.h garmin_fs.h jeeps/gps.h jeeps/../defs.h \
- jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h \
- jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \
- jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h \
- garmin_tables.h grtcirc.h jeeps/gpsserial.h
+ cet_util.h format.h garmin_device_xml.h garmin_fs.h jeeps/gps.h \
+ jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
+ jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
+ jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
+ jeeps/gpsrqst.h garmin_tables.h grtcirc.h jeeps/gpsserial.h vecs.h \
+ gpx.h src/core/file.h src/core/xmlstreamwriter.h src/core/xmltag.h \
+ legacyformat.h
garmin_device_xml.o: garmin_device_xml.cc defs.h config.h zlib/zlib.h \
zlib/zconf.h cet.h inifile.h gbfile.h session.h src/core/datetime.h \
src/core/optional.h garmin_device_xml.h xmlgeneric.h
garmin_fit.o: garmin_fit.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
cet.h inifile.h gbfile.h session.h src/core/datetime.h \
- src/core/optional.h
+ src/core/optional.h jeeps/gpsmath.h jeeps/gpsport.h
garmin_fs.o: garmin_fs.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
cet_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
cet_util.h magellan.h
gpx.o: gpx.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
- gbfile.h session.h src/core/datetime.h src/core/optional.h garmin_fs.h \
- jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h \
- jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h \
- jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h \
- jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h src/core/file.h \
- src/core/logging.h src/core/xmlstreamwriter.h src/core/xmltag.h
+ gbfile.h session.h src/core/datetime.h src/core/optional.h gpx.h \
+ format.h src/core/file.h src/core/xmlstreamwriter.h src/core/xmltag.h \
+ garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
+ jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
+ jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
+ jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h \
+ src/core/logging.h
grtcirc.o: grtcirc.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
grtcirc.h
xmlgeneric.h
height.o: height.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h height.h heightgrid.h
+ height.h filter.h heightgrid.h
hiketech.o: hiketech.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
src/core/xmlstreamwriter.h xmlgeneric.h
src/core/optional.h
interpolate.o: interpolate.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
cet.h inifile.h gbfile.h session.h src/core/datetime.h \
- src/core/optional.h filterdefs.h filter.h interpolate.h grtcirc.h
+ src/core/optional.h interpolate.h filter.h grtcirc.h
itracku.o: itracku.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
gbser.h
gbfile.h session.h src/core/datetime.h src/core/optional.h csv_util.h
kml.o: kml.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h grtcirc.h \
- src/core/file.h src/core/xmlstreamwriter.h src/core/xmltag.h \
- units.h xmlgeneric.h
+ src/core/file.h src/core/logging.h src/core/xmlstreamwriter.h \
+ src/core/xmltag.h units.h xmlgeneric.h
lmx.o: lmx.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h \
xmlgeneric.h
-lowranceusr.o: lowranceusr.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
- cet.h inifile.h gbfile.h session.h src/core/datetime.h \
- src/core/optional.h
+lowranceusr.o: lowranceusr.cc src/core/logging.h defs.h config.h \
+ zlib/zlib.h zlib/zconf.h cet.h inifile.h gbfile.h session.h \
+ src/core/datetime.h src/core/optional.h
maggeo.o: maggeo.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
csv_util.h magellan.h xmlgeneric.h
magproto.o: magproto.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- explorist_ini.h gbser.h magellan.h
+ explorist_ini.h format.h gbser.h magellan.h vecs.h gpx.h \
+ src/core/file.h src/core/xmlstreamwriter.h src/core/xmltag.h \
+ legacyformat.h
main.o: main.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h cet_util.h \
- csv_util.h filter.h filterdefs.h src/core/file.h \
- src/core/usasciicodec.h
+ csv_util.h filter.h filter_vecs.h arcdist.h bend.h discard.h \
+ duplicate.h height.h interpolate.h nukedata.h polygon.h position.h \
+ radius.h reverse_route.h smplrout.h sort.h stackfilter.h swapdata.h \
+ trackfilter.h transform.h validate.h format.h src/core/file.h \
+ src/core/usasciicodec.h vecs.h gpx.h src/core/xmlstreamwriter.h \
+ src/core/xmltag.h legacyformat.h
mapasia.o: mapasia.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
mapbar_track.o: mapbar_track.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
csv_util.h
nukedata.o: nukedata.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h nukedata.h
+ nukedata.h filter.h
osm.o: osm.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h \
xmlgeneric.h
src/core/optional.h csv_util.h
polygon.o: polygon.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h polygon.h
+ polygon.h filter.h
position.o: position.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h grtcirc.h position.h
+ grtcirc.h position.h filter.h
psitrex.o: psitrex.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
garmin_tables.h
radius.o: radius.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h radius.h grtcirc.h
+ radius.h filter.h grtcirc.h
random.o: random.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
csv_util.h
reverse_route.o: reverse_route.cc defs.h config.h zlib/zlib.h \
zlib/zconf.h cet.h inifile.h gbfile.h session.h src/core/datetime.h \
- src/core/optional.h filterdefs.h filter.h reverse_route.h
+ src/core/optional.h reverse_route.h filter.h
rgbcolors.o: rgbcolors.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
route.o: route.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
gbser.h
smplrout.o: smplrout.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h grtcirc.h smplrout.h
+ grtcirc.h smplrout.h filter.h
sort.o: sort.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
- gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h sort.h
+ gbfile.h session.h src/core/datetime.h src/core/optional.h sort.h \
+ filter.h
src/core/textstream.o: src/core/textstream.cc src/core/textstream.h \
src/core/file.h defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
src/core/xmlstreamwriter.h
stackfilter.o: stackfilter.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
cet.h inifile.h gbfile.h session.h src/core/datetime.h \
- src/core/optional.h filterdefs.h filter.h stackfilter.h
+ src/core/optional.h stackfilter.h filter.h
stmsdf.o: stmsdf.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
cet_util.h csv_util.h grtcirc.h jeeps/gpsmath.h jeeps/gpsport.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
swapdata.o: swapdata.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h swapdata.h
+ swapdata.h filter.h
tef_xml.o: tef_xml.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
xmlgeneric.h
jeeps/gpsmath.h jeeps/gpsport.h
trackfilter.o: trackfilter.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
cet.h inifile.h gbfile.h session.h src/core/datetime.h \
- src/core/optional.h filterdefs.h filter.h trackfilter.h grtcirc.h
+ src/core/optional.h trackfilter.h filter.h grtcirc.h
transform.o: transform.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h transform.h
+ transform.h filter.h
unicsv.o: unicsv.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
csv_util.h garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h garmin_tables.h \
src/core/logging.h src/core/textstream.h src/core/file.h
units.o: units.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
- inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h units.h
+ inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
+ units.h
util.o: util.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h \
src/core/xmltag.h
gbfile.h session.h src/core/datetime.h src/core/optional.h
validate.o: validate.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- filterdefs.h filter.h validate.h
+ validate.h filter.h
vcf.o: vcf.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h \
jeeps/gpsmath.h jeeps/gpsport.h
vecs.o: vecs.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
- gbfile.h session.h src/core/datetime.h src/core/optional.h csv_util.h \
- gbversion.h xcsv.h src/core/file.h
+ gbfile.h session.h src/core/datetime.h src/core/optional.h vecs.h \
+ format.h gpx.h src/core/file.h src/core/xmlstreamwriter.h \
+ src/core/xmltag.h legacyformat.h gbversion.h src/core/logging.h xcsv.h
vidaone.o: vidaone.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
vitosmt.o: vitosmt.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
src/core/optional.h cet_util.h src/core/file.h xmlgeneric.h
xmltag.o: xmltag.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h \
inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
- cet_util.h src/core/xmltag.h
+ src/core/xmltag.h
xol.o: xol.cc defs.h config.h zlib/zlib.h zlib/zconf.h cet.h inifile.h \
gbfile.h session.h src/core/datetime.h src/core/optional.h \
garmin_tables.h jeeps/gpsmath.h jeeps/gpsport.h src/core/file.h \
using ff_writeposn = void (*)(Waypoint*);
using ff_readposn = Waypoint* (*)(posn_status*);
-QString get_option(const QStringList& options, const char* argname);
-
geocache_type gs_mktype(const QString& t);
geocache_container gs_mkcont(const QString& t);
*/
struct ff_vecs_t {
ff_type type;
- ff_cap cap[3];
+ QVector<ff_cap> cap;
ff_init rd_init;
ff_init wr_init;
ff_deinit rd_deinit;
QString encode;
int fixed_encode;
position_ops_t position_ops;
- QString name; /* dyn. initialized by find_vec */
+ void* unused; /* TODO: delete this field */
};
struct style_vecs_t {
void warning(const char*, ...) PRINTFLIKE(1, 2);
void debug_print(int level, const char* fmt, ...) PRINTFLIKE(2,3);
-ff_vecs_t* find_vec(const QString&);
-void assign_option(const QString& vecname, arglist_t* arg, const char* val);
-void disp_vec_options(const QString& vecname, const QVector<arglist_t>* args);
-void disp_vecs();
-void disp_vec(const QString& vecname);
-void validate_options(const QStringList& options, const QVector<arglist_t>* args, const QString& name);
-bool validate_args(const QString& name, const QVector<arglist_t>* args);
-bool validate_formats();
-void init_vecs();
-void exit_vecs();
-void disp_formats(int version);
-const char* name_option(uint32_t type);
void printposn(double c, int is_lat);
void* xcalloc(size_t nmemb, size_t size);
#define CET_CHARSET_LATIN1 "ISO-8859-1"
/* this lives in gpx.c */
-gpsbabel::DateTime xml_parse_time(const QString& cdatastr);
+gpsbabel::DateTime xml_parse_time(const QString& dateTimeString);
QString rot13(const QString& s);
*/
-#include "defs.h"
-#include "arcdist.h"
-#include "bend.h"
-#include "discard.h"
-#include "duplicate.h"
-#include "filterdefs.h"
-#include "filter.h"
-#include "height.h"
-#include "interpolate.h"
-#include "nukedata.h"
-#include "polygon.h"
-#include "position.h"
-#include "radius.h"
-#include "reverse_route.h"
-#include "smplrout.h"
-#include "sort.h"
-#include "stackfilter.h"
-#include "swapdata.h"
-#include "trackfilter.h"
-#include "transform.h"
-#include "validate.h"
-#include "gbversion.h"
-#include "inifile.h"
-
#include <QtCore/QByteArray> // for QByteArray
#include <QtCore/QString> // for QString
#include <QtCore/QStringList> // for QStringList
#include <cassert> // for assert
#include <cstdio> // for printf
+#include "defs.h"
+#include "filter_vecs.h"
+#include "filter.h" // for Filter
+#include "gbversion.h" // for WEB_DOC_DIR
+#include "inifile.h" // for inifile_readstr
+#include "vecs.h" // for Vecs
-struct fl_vecs_t {
- Filter* vec;
- QString name;
- QString desc;
-};
-
-ArcDistanceFilter arcdist;
-BendFilter bend;
-DiscardFilter discard;
-DuplicateFilter duplicate;
-HeightFilter height;
-InterpolateFilter interpolate;
-NukeDataFilter nukedata;
-PolygonFilter polygon;
-PositionFilter position;
-RadiusFilter radius;
-ReverseRouteFilter reverse_route;
-SimplifyRouteFilter routesimple;
-SortFilter sort;
-StackFilter stackfilt;
-SwapDataFilter swapdata;
-TrackFilter trackfilter;
-TransformFilter transform;
-ValidateFilter validate;
-
-
-static
-const QVector<fl_vecs_t> filter_vec_list = {
-#if FILTERS_ENABLED
- {
- &arcdist,
- "arc",
- "Include Only Points Within Distance of Arc",
- },
- {
- &bend,
- "bend",
- "Add points before and after bends in routes"
- },
- {
- &discard,
- "discard",
- "Remove unreliable points with high hdop or vdop"
- },
- {
- &duplicate,
- "duplicate",
- "Remove Duplicates",
- },
- {
- &interpolate,
- "interpolate",
- "Interpolate between trackpoints"
- },
- {
- &nukedata,
- "nuketypes",
- "Remove all waypoints, tracks, or routes"
- },
- {
- &polygon,
- "polygon",
- "Include Only Points Inside Polygon",
- },
- {
- &position,
- "position",
- "Remove Points Within Distance",
- },
- {
- &radius,
- "radius",
- "Include Only Points Within Radius",
- },
- {
- &routesimple,
- "simplify",
- "Simplify routes",
- },
- {
- &sort,
- "sort",
- "Rearrange waypoints, routes and/or tracks by resorting",
- },
- {
- &stackfilt,
- "stack",
- "Save and restore waypoint lists"
- },
- {
- &reverse_route,
- "reverse",
- "Reverse stops within routes",
- },
- {
- &trackfilter,
- "track",
- "Manipulate track lists"
- },
- {
- &transform,
- "transform",
- "Transform waypoints into a route, tracks into routes, ..."
- },
- {
- &height,
- "height",
- "Manipulate altitudes"
- },
- {
- &swapdata,
- "swap",
- "Swap latitude and longitude of all loaded points"
- },
- {
- &validate,
- "validate",
- "Validate internal data structures"
- }
-#elif defined (MINIMAL_FILTERS)
- {
- &trackfilter,
- "track",
- "Manipulate track lists"
- }
-#endif
-};
-Filter*
-find_filter_vec(const QString& vecname)
+Filter* FilterVecs::find_filter_vec(const QString& vecname)
{
QStringList options = vecname.split(',');
if (options.isEmpty()) {
QVector<arglist_t>* args = vec.vec->get_args();
- validate_options(options, args, vec.name);
+ Vecs::validate_options(options, args, vec.name);
/* step 1: initialize by inifile or default values */
if (args && !args->isEmpty()) {
qtemp = inifile_readstr(global_opts.inifile, "Common filter settings", arg.argstring);
}
if (qtemp.isNull()) {
- assign_option(vec.name, &arg, arg.defaultvalue);
+ Vecs::assign_option(vec.name, &arg, arg.defaultvalue);
} else {
- assign_option(vec.name, &arg, CSTR(qtemp));
+ Vecs::assign_option(vec.name, &arg, CSTR(qtemp));
}
}
}
if (args && !args->isEmpty()) {
assert(args->isDetached());
for (auto& arg : *args) {
- const QString opt = get_option(options, arg.argstring);
+ const QString opt = Vecs::get_option(options, arg.argstring);
if (!opt.isNull()) {
- assign_option(vec.name, &arg, CSTR(opt));
+ Vecs::assign_option(vec.name, &arg, CSTR(opt));
}
}
}
}
if (global_opts.debug_level >= 1) {
- disp_vec_options(vec.name, args);
+ Vecs::disp_vec_options(vec.name, args);
}
return vec.vec;
return nullptr;
}
-void
-free_filter_vec(Filter* filter)
+void FilterVecs::free_filter_vec(Filter* filter)
{
QVector<arglist_t>* args = filter->get_args();
}
}
-void
-init_filter_vecs()
+void FilterVecs::init_filter_vecs()
{
for (const auto& vec : filter_vec_list) {
QVector<arglist_t>* args = vec.vec->get_args();
}
}
-void
-exit_filter_vecs()
+void FilterVecs::exit_filter_vecs()
{
for (const auto& vec : filter_vec_list) {
(vec.vec->exit)();
* Display the available formats in a format that's easy for humans to
* parse for help on available command line options.
*/
-void
-disp_filter_vecs()
+void FilterVecs::disp_filter_vecs() const
{
for (const auto& vec : filter_vec_list) {
printf(" %-20.20s %-50.50s\n",
const QVector<arglist_t>* args = vec.vec->get_args();
if (args) {
for (const auto& arg : *args) {
- if (!(arg.argtype & ARGTYPE_HIDDEN))
+ if (!(arg.argtype & ARGTYPE_HIDDEN)) {
printf(" %-18.18s %-.50s %s\n",
arg.argstring, arg.helpstring,
(arg.argtype & ARGTYPE_REQUIRED) ? "(required)" : "");
+ }
}
}
}
}
-void
-disp_filter_vec(const QString& vecname)
+void FilterVecs::disp_filter_vec(const QString& vecname) const
{
for (const auto& vec : filter_vec_list) {
if (vecname.compare(vec.name, Qt::CaseInsensitive) != 0) {
const QVector<arglist_t>* args = vec.vec->get_args();
if (args) {
for (const auto& arg : *args) {
- if (!(arg.argtype & ARGTYPE_HIDDEN))
+ if (!(arg.argtype & ARGTYPE_HIDDEN)) {
printf(" %-18.18s %-.50s %s\n",
arg.argstring, arg.helpstring,
(arg.argtype & ARGTYPE_REQUIRED) ? "(required)" : "");
+ }
}
}
}
}
-static
-void disp_help_url(const fl_vecs_t& vec, const arglist_t* arg)
+void FilterVecs::disp_help_url(const fl_vecs_t& vec, const arglist_t* arg)
{
printf("\t" WEB_DOC_DIR "/filter_%s.html", CSTR(vec.name));
if (arg) {
}
}
-static void
-disp_v1(const fl_vecs_t& vec)
+void FilterVecs::disp_v1(const fl_vecs_t& vec)
{
disp_help_url(vec, nullptr);
printf("\n");
CSTR(vec.name),
arg.argstring,
arg.helpstring,
- name_option(arg.argtype),
+ Vecs::name_option(arg.argtype),
arg.defaultvalue ? arg.defaultvalue : "",
arg.minvalue ? arg.minvalue : "",
arg.maxvalue ? arg.maxvalue : "");
* parse. Typically invoked by programs like graphical wrappers to
* determine what formats are supported.
*/
-void
-disp_filters(int version)
+void FilterVecs::disp_filters(int version) const
{
auto sorted_filter_vec_list = filter_vec_list;
}
}
-static bool
-validate_filter_vec(const fl_vecs_t& vec)
+bool FilterVecs::validate_filter_vec(const fl_vecs_t& vec)
{
- bool ok = validate_args(vec.name, vec.vec->get_args());
+ bool ok = Vecs::validate_args(vec.name, vec.vec->get_args());
return ok;
}
-bool validate_filters()
+bool FilterVecs::validate_filters() const
{
bool ok = true;
--- /dev/null
+/*
+ Describe vectors containing filter operations.
+
+ Copyright (C) 2002-2014 Robert Lipe, robertlipe+source@gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+#ifndef FILTER_VECS_H_INCLUDED_
+#define FILTER_VECS_H_INCLUDED_
+
+#include <QtCore/QString> // for QString
+#include <QtCore/QVector> // for QVector<>::iterator, QVector
+
+#include "defs.h" // for arglist_t
+#include "arcdist.h" // for ArcDistanceFilter
+#include "bend.h" // for BendFilter
+#include "discard.h" // for DiscardFilter
+#include "duplicate.h" // for DuplicateFilter
+#include "filter.h" // for Filter
+#include "height.h" // for HeightFilter
+#include "interpolate.h" // for InterpolateFilter
+#include "nukedata.h" // for NukeDataFilter
+#include "polygon.h" // for PolygonFilter
+#include "position.h" // for PositionFilter
+#include "radius.h" // for RadiusFilter
+#include "reverse_route.h" // for ReverseRouteFilter
+#include "smplrout.h" // for SimplifyRouteFilter
+#include "sort.h" // for SortFilter
+#include "stackfilter.h" // for StackFilter
+#include "swapdata.h" // for SwapDataFilter
+#include "trackfilter.h" // for TrackFilter
+#include "transform.h" // for TransformFilter
+#include "validate.h" // for ValidateFilter
+
+
+class FilterVecs
+{
+// Meyers Singleton
+public:
+ static FilterVecs& Instance()
+ {
+ static FilterVecs instance;
+ return instance;
+ }
+ FilterVecs(const FilterVecs&) = delete;
+ FilterVecs& operator= (const FilterVecs&) = delete;
+ FilterVecs(FilterVecs&&) = delete;
+ FilterVecs& operator=(FilterVecs&&) = delete;
+
+private:
+ FilterVecs() = default;
+ ~FilterVecs() = default;
+
+private:
+ struct fl_vecs_t {
+ Filter* vec;
+ QString name;
+ QString desc;
+ };
+
+public:
+Filter* find_filter_vec(const QString& vecname);
+static void free_filter_vec(Filter* filter);
+void init_filter_vecs();
+void exit_filter_vecs();
+void disp_filter_vecs() const;
+void disp_filter_vec(const QString& vecname) const;
+void disp_filters(int version) const;
+bool validate_filters() const;
+
+private:
+static void disp_help_url(const FilterVecs::fl_vecs_t& vec, const arglist_t* arg);
+static void disp_v1(const FilterVecs::fl_vecs_t& vec);
+static bool validate_filter_vec(const FilterVecs::fl_vecs_t& vec);
+
+private:
+ ArcDistanceFilter arcdist;
+ BendFilter bend;
+ DiscardFilter discard;
+ DuplicateFilter duplicate;
+ HeightFilter height;
+ InterpolateFilter interpolate;
+ NukeDataFilter nukedata;
+ PolygonFilter polygon;
+ PositionFilter position;
+ RadiusFilter radius;
+ ReverseRouteFilter reverse_route;
+ SimplifyRouteFilter routesimple;
+ SortFilter sort;
+ StackFilter stackfilt;
+ SwapDataFilter swapdata;
+ TrackFilter trackfilter;
+ TransformFilter transform;
+ ValidateFilter validate;
+
+ const QVector<fl_vecs_t> filter_vec_list = {
+#if FILTERS_ENABLED
+ {
+ &arcdist,
+ "arc",
+ "Include Only Points Within Distance of Arc",
+ },
+ {
+ &bend,
+ "bend",
+ "Add points before and after bends in routes"
+ },
+ {
+ &discard,
+ "discard",
+ "Remove unreliable points with high hdop or vdop"
+ },
+ {
+ &duplicate,
+ "duplicate",
+ "Remove Duplicates",
+ },
+ {
+ &interpolate,
+ "interpolate",
+ "Interpolate between trackpoints"
+ },
+ {
+ &nukedata,
+ "nuketypes",
+ "Remove all waypoints, tracks, or routes"
+ },
+ {
+ &polygon,
+ "polygon",
+ "Include Only Points Inside Polygon",
+ },
+ {
+ &position,
+ "position",
+ "Remove Points Within Distance",
+ },
+ {
+ &radius,
+ "radius",
+ "Include Only Points Within Radius",
+ },
+ {
+ &routesimple,
+ "simplify",
+ "Simplify routes",
+ },
+ {
+ &sort,
+ "sort",
+ "Rearrange waypoints, routes and/or tracks by resorting",
+ },
+ {
+ &stackfilt,
+ "stack",
+ "Save and restore waypoint lists"
+ },
+ {
+ &reverse_route,
+ "reverse",
+ "Reverse stops within routes",
+ },
+ {
+ &trackfilter,
+ "track",
+ "Manipulate track lists"
+ },
+ {
+ &transform,
+ "transform",
+ "Transform waypoints into a route, tracks into routes, ..."
+ },
+ {
+ &height,
+ "height",
+ "Manipulate altitudes"
+ },
+ {
+ &swapdata,
+ "swap",
+ "Swap latitude and longitude of all loaded points"
+ },
+ {
+ &validate,
+ "validate",
+ "Validate internal data structures"
+ }
+#elif defined (MINIMAL_FILTERS)
+ {
+ &trackfilter,
+ "track",
+ "Manipulate track lists"
+ }
+#endif
+ };
+};
+#endif // FILTER_VECS_H_INCLUDED_
+++ /dev/null
-/*
- Filter definitions.
-
- Copyright (C) 2005-2014 Robert Lipe, robertlipe+source@gpsbabel.org
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
- */
-
-#ifndef FILTERDEFS_H_INCLUDED_
-#define FILTERDEFS_H_INCLUDED_
-
-#include "defs.h"
-
-
-// forward declare filter to avoid exposing global_waypoint_list by filter.h
-class Filter;
-
-Filter* find_filter_vec(const QString&);
-void free_filter_vec(Filter*);
-void disp_filters(int version);
-void disp_filter_vec(const QString& vecname);
-void disp_filter_vecs();
-void init_filter_vecs();
-void exit_filter_vecs();
-bool validate_filters();
-
-#endif // FILTERDEFS_H_INCLUDED_
--- /dev/null
+/*
+
+ Format converter module skeleton.
+
+ Steps to create a new format.
+
+ 1) Copy this file to <your_format_name>.c
+ 2) Rename all format_skeleton tokens to <your_format_name>.
+ 3) Replace the fictional name and address in the Copyright section below.
+ ** As your work is likely built on the work of others, please retain
+ the original line. **
+ 4) Create a new section in vecs.c.
+ 5) Add compilation instructions to Makefile.
+ 6) Add sample files (it's better when they're created by the "real"
+ application and not our own output) to reference/ along with
+ files in a well supported (preferably non-binary) format and
+ entries in our 'testo' program. This allows users of different
+ OSes and hardware to exercise your module.
+
+ Copyright (C) YYYY John Doe, anybody@wherever.com
+ Copyright (C) 2001-YYYY Robert Lipe, robertlipe+source@gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+#ifndef FORMAT_H_INCLUDED_
+#define FORMAT_H_INCLUDED_
+
+#include "defs.h"
+
+
+class Format
+{
+public:
+ Format() = default;
+ // Provide virtual public destructor to avoid undefined behavior when
+ // an object of derived class type is deleted through a pointer to
+ // its base class type.
+ // https://wiki.sei.cmu.edu/confluence/display/cplusplus/OOP52-CPP.+Do+not+delete+a+polymorphic+object+without+a+virtual+destructor
+ virtual ~Format() = default;
+ // And that requires us to explicitly default or delete the move and copy operations.
+ // To prevent slicing we delete them.
+ // https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all.
+ Format(const Format&) = delete;
+ Format& operator=(const Format&) = delete;
+ Format(Format&&) = delete;
+ Format& operator=(Format&&) = delete;
+
+ /*******************************************************************************
+ * %%% global callbacks called by gpsbabel main process %%% *
+ *******************************************************************************/
+
+ virtual void rd_init(const QString& /* fname */)
+ {
+ fatal("Format does not support reading.\n");
+// fin = gbfopen(fname, "r", MYNAME);
+ }
+
+ virtual void rd_deinit()
+ {
+// gbfclose(fin);
+ }
+
+ virtual void read()
+ {
+// your special code to extract waypoint, route and track
+// information from gbfile "fin"
+//
+// Sample text-file read code:
+// char *s;
+// while ((s = gbfgetstr(fin))) {
+// do_anything(s);
+// }
+//
+//
+// For waypoints:
+// while (have waypoints) {
+// waypoint = new waypoint
+// populate waypoint
+// waypt_add(waypoint);
+// }
+//
+// For routes:
+//
+// route = route_head_alloc();
+// populate struct route_hdr
+// route_add_head(route);
+// while (have more routepoints) {
+// waypoint = new waypoint
+// populate waypoint
+// route_add_wpt(route, waypoint)
+// }
+//
+// Tracks are just like routes, except the word "track" replaces "routes".
+//
+ }
+
+ virtual void wr_init(const QString& /* fname */)
+ {
+ fatal("Format does not support writing.\n");
+// fout = gbfopen(fname, "w", MYNAME);
+ }
+
+ virtual void wr_deinit()
+ {
+// gbfclose(fout);
+ }
+
+ virtual void write()
+ {
+// Here is how you register callbacks for all waypoints, routes, tracks.
+// waypt_disp_all(waypt)
+// route_disp_all(head, tail, rtept);
+// track_disp_all(head, tail, trkpt);
+ }
+
+ virtual void exit() /* optional */
+ {
+ }
+
+ virtual void rd_position_init(const QString& /* fname */)
+ {
+ fatal("Realtime tracking (-T) is not suppored by this input type.\n");
+ }
+
+ virtual Waypoint* rd_position(posn_status* /* status */)
+ {
+ return nullptr;
+ }
+
+ virtual void rd_position_deinit()
+ {
+ }
+
+ virtual void wr_position_init(const QString& /* fname */)
+ {
+ }
+
+ virtual void wr_position(Waypoint* /* wpt */)
+ {
+ fatal("This output format does not support output of realtime positioning.\n");
+ }
+
+ virtual void wr_position_deinit()
+ {
+ }
+
+ /*******************************************************************************
+ * %%% Accessors %%% *
+ *******************************************************************************/
+
+ virtual QVector<arglist_t>* get_args()
+ {
+ return nullptr;
+ }
+
+ virtual ff_type get_type() const = 0;
+ virtual QVector<ff_cap> get_cap() const = 0;
+ virtual QString get_encode() const = 0;
+ virtual int get_fixed_encode() const = 0;
+
+ QString get_name() const
+ {
+ return name;
+ }
+
+ void set_name(QString nm)
+ {
+ name = nm;
+ }
+
+private:
+ QString name;
+
+protected:
+ template <class MyFormat>
+ class RteHdFunctor
+ {
+ public:
+ using RteHdCb = void (MyFormat::*)(const route_head*);
+ RteHdFunctor(MyFormat* obj, RteHdCb cb) : that(obj), _cb(cb) {}
+ void operator()(const route_head* rh)
+ {
+ ((that)->*(_cb))(rh);
+ }
+
+ private:
+ MyFormat* that;
+ RteHdCb _cb;
+ };
+
+ template <class MyFormat>
+ class WayptFunctor
+ {
+ public:
+ using WayptCb = void (MyFormat::*)(const Waypoint*);
+ WayptFunctor(MyFormat* obj, WayptCb cb) : that(obj), _cb(cb) {}
+ void operator()(const Waypoint* wpt)
+ {
+ ((that)->*(_cb))(wpt);
+ }
+
+ private:
+ MyFormat* that;
+ WayptCb _cb;
+ };
+
+};
+#endif // FORMAT_H_INCLUDED_
#include "defs.h"
#include "cet_util.h" // for cet_convert_init, cet_cs_vec_utf8
+#include "format.h" // for Format
#include "garmin_device_xml.h" // for gdx_get_info, gdx_info, gdx_file, gdx_jmp_buf
#include "garmin_fs.h" // for garmin_fs_garmin_after_read, garmin_fs_garmin_before_write
#include "garmin_tables.h" // for gt_find_icon_number_from_desc, PCX, gt_find_desc_from_icon_number
#include "jeeps/gps.h"
#include "jeeps/gpsserial.h"
#include "src/core/datetime.h" // for DateTime
+#include "vecs.h" // for Vecs
#define MYNAME "GARMIN"
static const char* portname;
static int categorybits;
static int receiver_must_upper = 1;
-static ff_vecs_t* gpx_vec;
+static Format* gpx_vec;
#define MILITANT_VALID_WAYPT_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
{
if (setjmp(gdx_jmp_buf)) {
const gdx_info* gi = gdx_get_info();
- gpx_vec = find_vec("gpx");
+ gpx_vec = Vecs::Instance().find_vec("gpx");
gpx_vec->rd_init(gi->from_device.canon);
} else {
gpx_vec = nullptr;
#include <QtCore/QtGlobal> // for qAsConst, QAddConst<>::Type
#include "defs.h"
-#include "garmin_fs.h"
-#include "garmin_tables.h"
-#include "src/core/datetime.h"
-#include "src/core/file.h"
-#include "src/core/logging.h"
-#include "src/core/xmlstreamwriter.h"
-#include "src/core/xmltag.h"
-
-
-static QXmlStreamReader* reader;
-static xml_tag* cur_tag;
-static QString cdatastr;
-static char* opt_logpoint = nullptr;
-static char* opt_humminbirdext = nullptr;
-static char* opt_garminext = nullptr;
-static char* opt_elevation_precision = nullptr;
-static int logpoint_ct = 0;
-static int elevation_precision;
-
-// static char* gpx_version = NULL;
-static QString gpx_version;
-static char* gpx_wversion;
-static int gpx_wversion_num;
-static QXmlStreamAttributes gpx_namespace_attribute;
-
-static QString current_tag;
-
-static Waypoint* wpt_tmp;
-static UrlLink* link_;
-static UrlLink* rh_link_;
-static bool cache_descr_is_html;
-static gpsbabel::File* iqfile;
-static gpsbabel::File* oqfile;
-static gpsbabel::XmlStreamWriter* writer;
-static short_handle mkshort_handle;
-static QString link_url;
-static QString link_text;
-static QString link_type;
-
-
-static char* snlen = nullptr;
-static char* suppresswhite = nullptr;
-static char* urlbase = nullptr;
-static route_head* trk_head;
-static route_head* rte_head;
-static const route_head* current_trk_head; // Output.
-/* used for bounds calculation on output */
-static bounds all_bounds;
-static int next_trkpt_is_new_seg;
-
-static format_specific_data** fs_ptr;
-static void gpx_write_bounds();
+#include "gpx.h"
+#include "garmin_fs.h" // for garmin_fs_xml_convert, garmin_fs_xml_fprint, GMSD_FIND
+#include "garmin_tables.h" // for gt_color_index_by_rgb, gt_color_name, gt_color_value_by_name
+#include "src/core/datetime.h" // for DateTime
+#include "src/core/file.h" // for File
+#include "src/core/logging.h" // for Warning, Fatal
+#include "src/core/xmlstreamwriter.h" // for XmlStreamWriter
+#include "src/core/xmltag.h" // for xml_tag, fs_xml, fs_xml_alloc, free_gpx_extras
#define MYNAME "GPX"
# define CREATOR_NAME_URL "GPSBabel - https://www.gpsbabel.org"
#endif
-enum gpx_point_type {
- gpxpt_waypoint,
- gpxpt_track,
- gpxpt_route
-};
-
-enum tag_type {
- tt_unknown = 0,
- tt_gpx,
-
- tt_name, /* Optional file-level info */
- tt_desc,
- tt_author,
- tt_email,
- tt_url,
- tt_urlname,
- tt_keywords,
- tt_link,
- tt_link_text,
- tt_link_type,
-
- tt_wpt,
- tt_wpttype_ele,
- tt_wpttype_time,
- tt_wpttype_geoidheight,
- tt_wpttype_name,
- tt_wpttype_cmt,
- tt_wpttype_desc,
- tt_wpttype_url, /* Not in GPX 1.1 */
- tt_wpttype_urlname, /* Not in GPX 1.1 */
- tt_wpttype_link, /* New in GPX 1.1 */
- tt_wpttype_link_text, /* New in GPX 1.1 */
- tt_wpttype_link_type, /* New in GPX 1.1 */
- tt_wpttype_sym,
- tt_wpttype_type,
- tt_wpttype_fix,
- tt_wpttype_sat,
- tt_wpttype_hdop, /* HDOPS are common for all three */
- tt_wpttype_vdop, /* VDOPS are common for all three */
- tt_wpttype_pdop, /* PDOPS are common for all three */
- tt_cache,
- tt_cache_name,
- tt_cache_container,
- tt_cache_type,
- tt_cache_difficulty,
- tt_cache_terrain,
- tt_cache_hint,
- tt_cache_desc_short,
- tt_cache_desc_long,
- tt_cache_log_wpt,
- tt_cache_log_type,
- tt_cache_log_date,
- tt_cache_placer,
- tt_cache_favorite_points,
- tt_cache_personal_note,
-
- tt_wpt_extensions,
-
- tt_garmin_wpt_extensions, /* don't change this order */
- tt_garmin_wpt_proximity,
- tt_garmin_wpt_temperature,
- tt_garmin_wpt_depth,
- tt_garmin_wpt_display_mode,
- tt_garmin_wpt_categories,
- tt_garmin_wpt_category,
- tt_garmin_wpt_addr,
- tt_garmin_wpt_city,
- tt_garmin_wpt_state,
- tt_garmin_wpt_country,
- tt_garmin_wpt_postal_code,
- tt_garmin_wpt_phone_nr, /* don't change this order */
-
- tt_rte,
- tt_rte_name,
- tt_rte_desc,
- tt_rte_cmt,
- tt_rte_url, /* Not in GPX 1.1 */
- tt_rte_urlname, /* Not in GPX 1.1 */
- tt_rte_link, /* New in GPX 1.1 */
- tt_rte_link_text, /* New in GPX 1.1 */
- tt_rte_link_type, /* New in GPX 1.1 */
- tt_rte_number,
- tt_garmin_rte_display_color,
- tt_rte_rtept,
- tt_trk,
- tt_trk_desc,
- tt_trk_name,
- tt_trk_trkseg,
- tt_trk_url, /* Not in GPX 1.1 */
- tt_trk_urlname, /* Not in GPX 1.1 */
- tt_trk_link, /* New in GPX 1.1 */
- tt_trk_link_text, /* New in GPX 1.1 */
- tt_trk_link_type, /* New in GPX 1.1 */
- tt_trk_number,
- tt_garmin_trk_display_color,
- tt_trk_trkseg_trkpt,
- tt_trk_trkseg_trkpt_course, /* Not in GPX 1.1 */
- tt_trk_trkseg_trkpt_speed, /* Not in GPX 1.1 */
- tt_trk_trkseg_trkpt_heartrate,
- tt_trk_trkseg_trkpt_cadence,
-
- tt_humminbird_wpt_depth,
- tt_humminbird_wpt_status,
- tt_humminbird_trk_trkseg_trkpt_depth,
-};
-
-/*
- * The file-level information.
- * This works for gpx 1.0, but does not handle all gpx 1.1 metadata.
- * TODO: gpx 1.1 metadata elements author, copyright, extensions,
- * all of which have more complicated content.
- * Note that all gpx 1.0 "global data" has a maxOccurs limit of one,
- * which is the default if maxOccurs is not in the xsd.
- * The only gpx 1.1 metadata that has a maxOccurs limit > one is link.
- * However, multiple gpx files may be read, and their global/metadata
- * combined, by this implementation.
- */
-struct GpxGlobal {
- QStringList name;
- QStringList desc;
- QStringList author;
- QStringList email;
- QStringList url;
- QStringList urlname;
- QStringList keywords;
- UrlList link;
- /* time and bounds aren't here; they're recomputed. */
-};
-static GpxGlobal* gpx_global = nullptr;
-
-static void
-gpx_add_to_global(QStringList& ge, const QString& s)
+void
+GpxFormat::gpx_add_to_global(QStringList& ge, const QString& s)
{
if (!ge.contains(s)) {
ge.append(s);
// Temporarily mock the old GPX writer's hardcoded fixed length for float/double
// types. This can be removed once we have time/interest in regenerating all our
// zillion reference files.
-static inline QString toString(double d)
+inline QString GpxFormat::toString(double d)
{
return QString::number(d, 'f', 9);
}
-static inline QString toString(float f)
+inline QString GpxFormat::toString(float f)
{
return QString::number(f, 'f', 6);
}
* gpx_reset_short_handle: used for waypoint, route and track names
* this allows gpx:wpt names to overlap gpx:rtept names, etc.
*/
-static void
-gpx_reset_short_handle()
+void
+GpxFormat::gpx_reset_short_handle()
{
if (mkshort_handle != nullptr) {
mkshort_del_handle(&mkshort_handle);
setshort_length(mkshort_handle, atoi(snlen));
}
-static void
-gpx_write_gdata(const QStringList& ge, const QString& tag)
+void
+GpxFormat::gpx_write_gdata(const QStringList& ge, const QString& tag)
{
if (!ge.isEmpty()) {
writer->writeStartElement(tag);
}
}
-
-struct tag_mapping {
- tag_type tag_type_; /* enum from above for this tag */
- int tag_passthrough; /* true if we don't generate this */
- const char* tag_name; /* xpath-ish tag name */
-};
-
-/*
- * xpath(ish) mappings between full tag paths and internal identifiers.
- * These appear in the order they appear in the GPX specification.
- * If it's not a tag we explicitly handle, it doesn't go here.
- */
-
-/* /gpx/<name> for GPX 1.0, /gpx/metadata/<name> for GPX 1.1 */
-#define METATAG(type,name) \
- {type, 0, "/gpx/" name}, \
- {type, 0, "/gpx/metadata/" name}
-
-static tag_mapping tag_path_map[] = {
- { tt_gpx, 0, "/gpx" },
- METATAG(tt_name, "name"),
- METATAG(tt_desc, "desc"),
- { tt_author, 0, "/gpx/author" },
- { tt_email, 0, "/gpx/email" },
- { tt_url, 0, "/gpx/url" },
- { tt_urlname, 0, "/gpx/urlname" },
- METATAG(tt_keywords, "keywords"),
- { tt_link, 0, "/gpx/metadata/link" },
- { tt_link_text, 0, "/gpx/metadata/link/text" },
- { tt_link_type, 0, "/gpx/metadata/link/type" },
-
- { tt_wpt, 0, "/gpx/wpt" },
-
- /* Double up the GPX 1.0 and GPX 1.1 styles */
-#define GEOTAG(type,name) \
- {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name }, \
- {type, 1, "/gpx/wpt/extensions/cache/" name }, \
- {type, 1, "/gpx/wpt/geocache/" name } /* opencaching.de */
-
-#define GARMIN_RTE_EXT "/gpx/rte/extensions/gpxx:RouteExtension"
-#define GARMIN_TRK_EXT "/gpx/trk/extensions/gpxx:TrackExtension"
-#define GARMIN_WPT_EXT "/gpx/wpt/extensions/gpxx:WaypointExtension"
-#define GARMIN_TRKPT_EXT "/gpx/trk/trkseg/trkpt/extensions/gpxtpx:TrackPointExtension"
-#define GARMIN_RTEPT_EXT "/gpx/rte/rtept/extensions/gpxxx:RoutePointExtension"
-
-// GEOTAG( tt_cache, "cache"),
- { tt_cache, 1, "/gpx/wpt/groundspeak:cache" },
-
- GEOTAG(tt_cache_name, "name"),
- GEOTAG(tt_cache_container, "container"),
- GEOTAG(tt_cache_type, "type"),
- GEOTAG(tt_cache_difficulty, "difficulty"),
- GEOTAG(tt_cache_terrain, "terrain"),
- GEOTAG(tt_cache_hint, "encoded_hints"),
- GEOTAG(tt_cache_hint, "hints"), /* opencaching.de */
- GEOTAG(tt_cache_desc_short, "short_description"),
- GEOTAG(tt_cache_desc_long, "long_description"),
- GEOTAG(tt_cache_placer, "owner"),
- GEOTAG(tt_cache_favorite_points, "favorite_points"),
- GEOTAG(tt_cache_personal_note, "personal_note"),
- { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"},
- { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"},
- { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"},
- { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"},
- { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"},
- { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"},
-
- { tt_wpt_extensions, 0, "/gpx/wpt/extensions" },
-
- { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT },
- { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity" },
- { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature" },
- { tt_garmin_wpt_temperature, 1, GARMIN_TRKPT_EXT "/gpxtpx:atemp" },
- { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth" },
- { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode" },
- { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories" },
- { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category" },
- { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress" },
- { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City" },
- { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State" },
- { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country" },
- { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode" },
- { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber"},
-
- // In Garmin space, but in core of waypoint.
- { tt_trk_trkseg_trkpt_heartrate, 1, GARMIN_TRKPT_EXT "/gpxtpx:hr" },
- { tt_trk_trkseg_trkpt_cadence, 1, GARMIN_TRKPT_EXT "/gpxtpx:cad" },
-
- { tt_humminbird_wpt_depth, 0, "/gpx/wpt/extensions/h:depth" }, // in centimeters.
- { tt_humminbird_wpt_status, 0, "/gpx/wpt/extensions/h:status" },
-
- { tt_rte, 0, "/gpx/rte" },
- { tt_rte_name, 0, "/gpx/rte/name" },
- { tt_rte_desc, 0, "/gpx/rte/desc" },
- { tt_rte_url, 0, "/gpx/rte/url"}, /* GPX 1.0 */
- { tt_rte_urlname, 0, "/gpx/rte/urlname"}, /* GPX 1.0 */
- { tt_rte_link, 0, "/gpx/rte/link"}, /* GPX 1.1 */
- { tt_rte_link_text, 0, "/gpx/rte/link/text"}, /* GPX 1.1 */
- { tt_rte_link_type, 0, "/gpx/rte/link/type"}, /* GPX 1.1 */
- { tt_rte_number, 0, "/gpx/rte/number" },
- { tt_garmin_rte_display_color, 1, GARMIN_RTE_EXT "/gpxx:DisplayColor"},
-
- { tt_rte_rtept, 0, "/gpx/rte/rtept" },
-
- { tt_trk, 0, "/gpx/trk" },
- { tt_trk_name, 0, "/gpx/trk/name" },
- { tt_trk_desc, 0, "/gpx/trk/desc" },
- { tt_trk_trkseg, 0, "/gpx/trk/trkseg" },
- { tt_trk_url, 0, "/gpx/trk/url"}, /* GPX 1.0 */
- { tt_trk_urlname, 0, "/gpx/trk/urlname"}, /* GPX 1.0 */
- { tt_trk_link, 0, "/gpx/trk/link"}, /* GPX 1.1 */
- { tt_trk_link_text, 0, "/gpx/trk/link/text"}, /* GPX 1.1 */
- { tt_trk_link_type, 0, "/gpx/trk/link/type"}, /* GPX 1.1 */
- { tt_trk_number, 0, "/gpx/trk/number" },
- { tt_garmin_trk_display_color, 1, GARMIN_TRK_EXT "/gpxx:DisplayColor"},
-
- { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt" },
- { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course" },
- { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed" },
-
- { tt_humminbird_trk_trkseg_trkpt_depth, 0, "/gpx/trk/trkseg/trkpt/extensions/h:depth" }, // in centimeters.
-
- /* Common to tracks, routes, and waypts */
-#define GPXWPTTYPETAG(type,passthrough,name) \
- {type, passthrough, "/gpx/wpt/" name }, \
- {type, passthrough, "/gpx/trk/trkseg/trkpt/" name }, \
- {type, passthrough, "/gpx/rte/rtept/" name }
-
- GPXWPTTYPETAG(tt_wpttype_ele, 0, "ele"),
- GPXWPTTYPETAG(tt_wpttype_time, 0, "time"),
- GPXWPTTYPETAG(tt_wpttype_geoidheight, 0, "geoidheight"),
- GPXWPTTYPETAG(tt_wpttype_name, 0, "name"),
- GPXWPTTYPETAG(tt_wpttype_cmt, 0, "cmt"),
- GPXWPTTYPETAG(tt_wpttype_desc, 0, "desc"),
- GPXWPTTYPETAG(tt_wpttype_url, 0, "url"), /* GPX 1.0 */
- GPXWPTTYPETAG(tt_wpttype_urlname, 0, "urlname"), /* GPX 1.0 */
- GPXWPTTYPETAG(tt_wpttype_link, 0, "link"), /* GPX 1.1 */
- GPXWPTTYPETAG(tt_wpttype_link_text, 0, "link/text"), /* GPX 1.1 */
- GPXWPTTYPETAG(tt_wpttype_link_type, 0, "link/type"), /* GPX 1.1 */
- GPXWPTTYPETAG(tt_wpttype_sym, 0, "sym"),
- GPXWPTTYPETAG(tt_wpttype_type, 1, "type"),
- GPXWPTTYPETAG(tt_wpttype_fix, 0, "fix"),
- GPXWPTTYPETAG(tt_wpttype_sat, 0, "sat"),
- GPXWPTTYPETAG(tt_wpttype_hdop, 0, "hdop"),
- GPXWPTTYPETAG(tt_wpttype_vdop, 0, "vdop"),
- GPXWPTTYPETAG(tt_wpttype_pdop, 0, "pdop"),
-
- {(tag_type)0, 0, nullptr}
-};
-
-// Maintain a fast mapping from full tag names to the struct above.
-static QHash<QString, tag_mapping*> hash;
-
-static tag_type
-get_tag(const QString& t, int* passthrough)
+GpxFormat::tag_type
+GpxFormat::get_tag(const QString& t, int* passthrough)
{
tag_mapping* tm = hash[t];
if (tm) {
return tt_unknown;
}
-static void
-prescan_tags()
+void
+GpxFormat::prescan_tags()
{
for (tag_mapping* tm = tag_path_map; tm->tag_type_ != 0; tm++) {
hash[tm->tag_name] = tm;
}
}
-static void
-tag_gpx(const QXmlStreamAttributes& attr)
+void
+GpxFormat::tag_gpx(const QXmlStreamAttributes& attr)
{
if (attr.hasAttribute("version")) {
/* Set the default output version to the highest input
}
}
-static void
-tag_wpt(const QXmlStreamAttributes& attr)
+void
+GpxFormat::tag_wpt(const QXmlStreamAttributes& attr)
{
wpt_tmp = new Waypoint;
link_ = new UrlLink;
fs_ptr = &wpt_tmp->fs;
}
-static void
-tag_cache_desc(const QXmlStreamAttributes& attr)
+void
+GpxFormat::tag_cache_desc(const QXmlStreamAttributes& attr)
{
cache_descr_is_html = false;
if (attr.hasAttribute("html")) {
}
}
-static void
-tag_gs_cache(const QXmlStreamAttributes& attr)
+void
+GpxFormat::tag_gs_cache(const QXmlStreamAttributes& attr)
{
geocache_data* gc_data = wpt_tmp->AllocGCData();
}
}
-static void
-start_something_else(const QString& el, const QXmlStreamAttributes& attr)
+void
+GpxFormat::start_something_else(const QString& el, const QXmlStreamAttributes& attr)
{
if (!fs_ptr) {
return;
cur_tag = new_tag;
}
-static void
-end_something_else()
+void
+GpxFormat::end_something_else()
{
if (cur_tag) {
cur_tag = cur_tag->parent;
}
}
-static void
-tag_log_wpt(const QXmlStreamAttributes& attr)
+void
+GpxFormat::tag_log_wpt(const QXmlStreamAttributes& attr)
{
/* create a new waypoint */
auto* lwp_tmp = new Waypoint;
}
}
-static void
-gpx_start(const QString& el, const QXmlStreamAttributes& attr)
+void
+GpxFormat::gpx_start(const QString& el, const QXmlStreamAttributes& attr)
{
int passthrough;
return dt;
}
-static void
-gpx_end(const QString&)
+void
+GpxFormat::gpx_end(const QString& /*unused*/)
{
int passthrough;
static QDateTime gc_log_date;
}
-static void
-gpx_cdata(const QString& s)
+void
+GpxFormat::gpx_cdata(const QString& s)
{
QString* cdata;
cdatastr += s;
*cdata = cdatastr.trimmed();
}
-static void
-gpx_rd_init(const QString& fname)
+void
+GpxFormat::rd_init(const QString& fname)
{
iqfile = new gpsbabel::File(fname);
iqfile->open(QIODevice::ReadOnly);
fs_ptr = nullptr;
}
-static
void
-gpx_rd_deinit()
+GpxFormat::rd_deinit()
{
delete reader;
reader = nullptr;
cur_tag = nullptr;
}
-static void
-gpx_wr_init(const QString& fname)
+void
+GpxFormat::wr_init(const QString& fname)
{
mkshort_handle = nullptr;
oqfile = new gpsbabel::File(fname);
}
-static void
-gpx_wr_deinit()
+void
+GpxFormat::wr_deinit()
{
writer->writeEndDocument();
delete writer;
mkshort_del_handle(&mkshort_handle);
}
-static void
-gpx_read()
+void
+GpxFormat::read()
{
for (bool atEnd = false; !reader->atEnd() && !atEnd;) {
reader->readNext();
}
}
-static void
-write_attributes(const QXmlStreamAttributes& attributes)
+void
+GpxFormat::write_attributes(const QXmlStreamAttributes& attributes)
{
for (const auto& attribute : attributes) {
writer->writeAttribute(attribute.qualifiedName().toString(), attribute.value().toString());
}
}
-static void
-fprint_xml_chain(xml_tag* tag, const Waypoint* wpt)
+void
+GpxFormat::fprint_xml_chain(xml_tag* tag, const Waypoint* wpt)
{
while (tag) {
writer->writeStartElement(tag->tagname);
/*
* Handle the grossness of GPX 1.0 vs. 1.1 handling of linky links.
*/
-static void
-write_gpx_url(const UrlList& urls)
+void
+GpxFormat::write_gpx_url(const UrlList& urls)
{
if (gpx_wversion_num > 10) {
for (const auto& l : urls) {
}
}
-static void
-write_gpx_url(const Waypoint* waypointp)
+void
+GpxFormat::write_gpx_url(const Waypoint* waypointp)
{
if (waypointp->HasUrlLink()) {
write_gpx_url(waypointp->urls);
}
}
-static void
-write_gpx_url(const route_head* rh)
+void
+GpxFormat::write_gpx_url(const route_head* rh)
{
if (rh->rte_urls.HasUrlLink()) {
write_gpx_url(rh->rte_urls);
* to the output stream. Done in one place since it's common for all three.
* Order counts.
*/
-static void
-gpx_write_common_acc(const Waypoint* waypointp)
+void
+GpxFormat::gpx_write_common_acc(const Waypoint* waypointp)
{
const char* fix = nullptr;
}
-static void
-gpx_write_common_position(const Waypoint* waypointp, const gpx_point_type point_type)
+void
+GpxFormat::gpx_write_common_position(const Waypoint* waypointp, const gpx_point_type point_type)
{
if (waypointp->altitude != unknown_alt) {
writer->writeTextElement(QStringLiteral("ele"), QString::number(waypointp->altitude, 'f', elevation_precision));
}
}
-static void
-gpx_write_common_extensions(const Waypoint* waypointp, const gpx_point_type point_type)
+void
+GpxFormat::gpx_write_common_extensions(const Waypoint* waypointp, const gpx_point_type point_type)
{
// gpx version we are writing is >= 1.1.
if ((opt_humminbirdext && (WAYPT_HAS(waypointp, depth) || WAYPT_HAS(waypointp, temperature))) ||
}
}
-static void
-gpx_write_common_description(const Waypoint* waypointp, const QString& oname)
+void
+GpxFormat::gpx_write_common_description(const Waypoint* waypointp, const QString& oname)
{
writer->writeOptionalTextElement(QStringLiteral("name"), oname);
/* TODO: type should go here */
}
-static void
-gpx_waypt_pr(const Waypoint* waypointp)
+void
+GpxFormat::gpx_waypt_pr(const Waypoint* waypointp)
{
writer->writeStartElement(QStringLiteral("wpt"));
writer->writeAttribute(QStringLiteral("lat"), toString(waypointp->latitude));
writer->writeEndElement();
}
-static void
-gpx_track_hdr(const route_head* rte)
+void
+GpxFormat::gpx_track_hdr(const route_head* rte)
{
current_trk_head = rte;
}
}
-static void
-gpx_track_disp(const Waypoint* waypointp)
+void
+GpxFormat::gpx_track_disp(const Waypoint* waypointp)
{
bool first_in_trk = waypointp == current_trk_head->waypoint_list.front();
writer->writeEndElement();
}
-static void
-gpx_track_tlr(const route_head*)
+void
+GpxFormat::gpx_track_tlr(const route_head* /*unused*/)
{
if (!current_trk_head->waypoint_list.empty()) {
writer->writeEndElement();
current_trk_head = nullptr;
}
-static
-void gpx_track_pr()
+void
+GpxFormat::gpx_track_pr()
{
- track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp);
+ auto gpx_track_hdr_lambda = [this](const route_head* rte)->void {
+ gpx_track_hdr(rte);
+ };
+ auto gpx_track_tlr_lambda = [this](const route_head* rte)->void {
+ gpx_track_tlr(rte);
+ };
+ auto gpx_track_disp_lambda = [this](const Waypoint* waypointp)->void {
+ gpx_track_disp(waypointp);
+ };
+ track_disp_all(gpx_track_hdr_lambda, gpx_track_tlr_lambda, gpx_track_disp_lambda);
}
-static void
-gpx_route_hdr(const route_head* rte)
+void
+GpxFormat::gpx_route_hdr(const route_head* rte)
{
writer->writeStartElement(QStringLiteral("rte"));
writer->writeOptionalTextElement(QStringLiteral("name"), rte->rte_name);
}
}
-static void
-gpx_route_disp(const Waypoint* waypointp)
+void
+GpxFormat::gpx_route_disp(const Waypoint* waypointp)
{
writer->writeStartElement(QStringLiteral("rtept"));
writer->writeAttribute(QStringLiteral("lat"), toString(waypointp->latitude));
writer->writeEndElement();
}
-static void
-gpx_route_tlr(const route_head*)
+void
+GpxFormat::gpx_route_tlr(const route_head* /*unused*/)
{
writer->writeEndElement(); // Close rte tag.
}
-static
-void gpx_route_pr()
+void
+GpxFormat::gpx_route_pr()
{
/* output routes */
- route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp);
+ auto gpx_route_hdr_lambda = [this](const route_head* rte)->void {
+ gpx_route_hdr(rte);
+ };
+ auto gpx_route_tlr_lambda = [this](const route_head* rte)->void {
+ gpx_route_tlr(rte);
+ };
+ auto gpx_route_disp_lambda = [this](const Waypoint* waypointp)->void {
+ gpx_route_disp(waypointp);
+ };
+ route_disp_all(gpx_route_hdr_lambda, gpx_route_tlr_lambda, gpx_route_disp_lambda);
}
-static void
-gpx_waypt_bound_calc(const Waypoint* waypointp)
+void
+GpxFormat::gpx_waypt_bound_calc(const Waypoint* waypointp)
{
waypt_add_to_bounds(&all_bounds, waypointp);
}
-static void
-gpx_write_bounds()
+void
+GpxFormat::gpx_write_bounds()
{
waypt_init_bounds(&all_bounds);
- waypt_disp_all(gpx_waypt_bound_calc);
- route_disp_all(nullptr, nullptr, gpx_waypt_bound_calc);
- track_disp_all(nullptr, nullptr, gpx_waypt_bound_calc);
+ auto gpx_waypt_bound_calc_lambda = [this](const Waypoint* waypointp)->void {
+ gpx_waypt_bound_calc(waypointp);
+ };
+ waypt_disp_all(gpx_waypt_bound_calc_lambda);
+ route_disp_all(nullptr, nullptr, gpx_waypt_bound_calc_lambda);
+ track_disp_all(nullptr, nullptr, gpx_waypt_bound_calc_lambda);
if (waypt_bounds_valid(&all_bounds)) {
writer->writeStartElement(QStringLiteral("bounds"));
}
}
-static void
-gpx_write()
+void
+GpxFormat::write()
{
elevation_precision = atoi(opt_elevation_precision);
gpx_reset_short_handle();
- waypt_disp_all(gpx_waypt_pr);
+ auto gpx_waypt_pr_lambda = [this](const Waypoint* waypointp)->void {
+ gpx_waypt_pr(waypointp);
+ };
+ waypt_disp_all(gpx_waypt_pr_lambda);
gpx_reset_short_handle();
gpx_route_pr();
gpx_reset_short_handle();
writer->writeEndElement(); // Close gpx tag.
}
-static void
-gpx_exit()
+void
+GpxFormat::exit()
{
gpx_version.clear();
delete gpx_global;
gpx_global = nullptr;
}
-
-static
-QVector<arglist_t> gpx_args = {
- {
- "snlen", &snlen, "Length of generated shortnames",
- "32", ARGTYPE_INT, "1", nullptr, nullptr
- },
- {
- "suppresswhite", &suppresswhite,
- "No whitespace in generated shortnames",
- nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
- },
- {
- "logpoint", &opt_logpoint,
- "Create waypoints from geocache log entries",
- nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
- },
- {
- "urlbase", &urlbase, "Base URL for link tag in output",
- nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr
- },
- {
- "gpxver", &gpx_wversion, "Target GPX version for output",
- nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr
- },
- {
- "humminbirdextensions", &opt_humminbirdext,
- "Add info (depth) as Humminbird extension",
- nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
- },
- {
- "garminextensions", &opt_garminext,
- "Add info (depth) as Garmin extension",
- nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
- },
- {
- "elevprec", &opt_elevation_precision,
- "Precision of elevations, number of decimals",
- "3", ARGTYPE_INT, ARG_NOMINMAX, nullptr
- },
-};
-
-ff_vecs_t gpx_vecs = {
- ff_type_file,
- FF_CAP_RW_ALL,
- gpx_rd_init,
- gpx_wr_init,
- gpx_rd_deinit,
- gpx_wr_deinit,
- gpx_read,
- gpx_write,
- gpx_exit,
- &gpx_args,
- CET_CHARSET_UTF8, 0, /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */
- NULL_POS_OPS,
- nullptr,
-};
--- /dev/null
+/*
+ Access GPX data files.
+
+ Copyright (C) 2002-2015 Robert Lipe, gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+#ifndef GPX_H_INCLUDED_
+#define GPX_H_INCLUDED_
+
+#include <QtCore/QHash> // for QHash
+#include <QtCore/QString> // for QString
+#include <QtCore/QStringList> // for QStringList
+#include <QtCore/QVector> // for QVector
+#include <QtCore/QXmlStreamAttributes> // for QXmlStreamAttributes
+#include <QtCore/QXmlStreamReader> // for QXmlStreamReader
+
+#include "defs.h"
+#include "format.h" // for Format
+#include "src/core/file.h" // for File
+#include "src/core/xmlstreamwriter.h" // for XmlStreamWriter
+#include "src/core/xmltag.h" // for xml_tag
+
+
+class GpxFormat : public Format
+{
+public:
+ QVector<arglist_t>* get_args() override
+ {
+ return &gpx_args;
+ }
+
+ ff_type get_type() const override
+ {
+ return ff_type_file;
+ }
+
+ QVector<ff_cap> get_cap() const override
+ {
+ return FF_CAP_RW_ALL;
+ }
+
+ QString get_encode() const override
+ {
+ return CET_CHARSET_UTF8;
+ }
+
+ int get_fixed_encode() const override
+ {
+ return 0;
+ }
+
+ void rd_init(const QString& fname) override;
+ void read() override;
+ void rd_deinit() override;
+ void wr_init(const QString& fname) override;
+ void write() override;
+ void wr_deinit() override;
+ void exit() override;
+
+private:
+ enum gpx_point_type {
+ gpxpt_waypoint,
+ gpxpt_track,
+ gpxpt_route
+ };
+
+ enum tag_type {
+ tt_unknown = 0,
+ tt_gpx,
+
+ tt_name, /* Optional file-level info */
+ tt_desc,
+ tt_author,
+ tt_email,
+ tt_url,
+ tt_urlname,
+ tt_keywords,
+ tt_link,
+ tt_link_text,
+ tt_link_type,
+
+ tt_wpt,
+ tt_wpttype_ele,
+ tt_wpttype_time,
+ tt_wpttype_geoidheight,
+ tt_wpttype_name,
+ tt_wpttype_cmt,
+ tt_wpttype_desc,
+ tt_wpttype_url, /* Not in GPX 1.1 */
+ tt_wpttype_urlname, /* Not in GPX 1.1 */
+ tt_wpttype_link, /* New in GPX 1.1 */
+ tt_wpttype_link_text, /* New in GPX 1.1 */
+ tt_wpttype_link_type, /* New in GPX 1.1 */
+ tt_wpttype_sym,
+ tt_wpttype_type,
+ tt_wpttype_fix,
+ tt_wpttype_sat,
+ tt_wpttype_hdop, /* HDOPS are common for all three */
+ tt_wpttype_vdop, /* VDOPS are common for all three */
+ tt_wpttype_pdop, /* PDOPS are common for all three */
+ tt_cache,
+ tt_cache_name,
+ tt_cache_container,
+ tt_cache_type,
+ tt_cache_difficulty,
+ tt_cache_terrain,
+ tt_cache_hint,
+ tt_cache_desc_short,
+ tt_cache_desc_long,
+ tt_cache_log_wpt,
+ tt_cache_log_type,
+ tt_cache_log_date,
+ tt_cache_placer,
+ tt_cache_favorite_points,
+ tt_cache_personal_note,
+
+ tt_wpt_extensions,
+
+ tt_garmin_wpt_extensions, /* don't change this order */
+ tt_garmin_wpt_proximity,
+ tt_garmin_wpt_temperature,
+ tt_garmin_wpt_depth,
+ tt_garmin_wpt_display_mode,
+ tt_garmin_wpt_categories,
+ tt_garmin_wpt_category,
+ tt_garmin_wpt_addr,
+ tt_garmin_wpt_city,
+ tt_garmin_wpt_state,
+ tt_garmin_wpt_country,
+ tt_garmin_wpt_postal_code,
+ tt_garmin_wpt_phone_nr, /* don't change this order */
+
+ tt_rte,
+ tt_rte_name,
+ tt_rte_desc,
+ tt_rte_cmt,
+ tt_rte_url, /* Not in GPX 1.1 */
+ tt_rte_urlname, /* Not in GPX 1.1 */
+ tt_rte_link, /* New in GPX 1.1 */
+ tt_rte_link_text, /* New in GPX 1.1 */
+ tt_rte_link_type, /* New in GPX 1.1 */
+ tt_rte_number,
+ tt_garmin_rte_display_color,
+ tt_rte_rtept,
+ tt_trk,
+ tt_trk_desc,
+ tt_trk_name,
+ tt_trk_trkseg,
+ tt_trk_url, /* Not in GPX 1.1 */
+ tt_trk_urlname, /* Not in GPX 1.1 */
+ tt_trk_link, /* New in GPX 1.1 */
+ tt_trk_link_text, /* New in GPX 1.1 */
+ tt_trk_link_type, /* New in GPX 1.1 */
+ tt_trk_number,
+ tt_garmin_trk_display_color,
+ tt_trk_trkseg_trkpt,
+ tt_trk_trkseg_trkpt_course, /* Not in GPX 1.1 */
+ tt_trk_trkseg_trkpt_speed, /* Not in GPX 1.1 */
+ tt_trk_trkseg_trkpt_heartrate,
+ tt_trk_trkseg_trkpt_cadence,
+
+ tt_humminbird_wpt_depth,
+ tt_humminbird_wpt_status,
+ tt_humminbird_trk_trkseg_trkpt_depth,
+ };
+
+
+ void gpx_add_to_global(QStringList& ge, const QString& s);
+ inline QString toString(double d);
+ inline QString toString(float f);
+ void gpx_reset_short_handle();
+ void gpx_write_gdata(const QStringList& ge, const QString& tag);
+ tag_type get_tag(const QString& t, int* passthrough);
+ void prescan_tags();
+ void tag_gpx(const QXmlStreamAttributes& attr);
+ void tag_wpt(const QXmlStreamAttributes& attr);
+ void tag_cache_desc(const QXmlStreamAttributes& attr);
+ void tag_gs_cache(const QXmlStreamAttributes& attr);
+ void start_something_else(const QString& el, const QXmlStreamAttributes& attr);
+ void end_something_else();
+ void tag_log_wpt(const QXmlStreamAttributes& attr);
+ void gpx_start(const QString& el, const QXmlStreamAttributes& attr);
+ void gpx_end(const QString& unused);
+ void gpx_cdata(const QString& s);
+ void write_attributes(const QXmlStreamAttributes& attributes);
+ void fprint_xml_chain(xml_tag* tag, const Waypoint* wpt);
+ void write_gpx_url(const UrlList& urls);
+ void write_gpx_url(const Waypoint* waypointp);
+ void write_gpx_url(const route_head* rh);
+ void gpx_write_common_acc(const Waypoint* waypointp);
+ void gpx_write_common_position(const Waypoint* waypointp, gpx_point_type point_type);
+ void gpx_write_common_extensions(const Waypoint* waypointp, gpx_point_type point_type);
+ void gpx_write_common_description(const Waypoint* waypointp, const QString& oname);
+ void gpx_waypt_pr(const Waypoint* waypointp);
+ void gpx_track_hdr(const route_head* rte);
+ void gpx_track_disp(const Waypoint* waypointp);
+ void gpx_track_tlr(const route_head* unused);
+ void gpx_track_pr();
+ void gpx_route_hdr(const route_head* rte);
+ void gpx_route_disp(const Waypoint* waypointp);
+ void gpx_route_tlr(const route_head* unused);
+ void gpx_route_pr();
+ void gpx_waypt_bound_calc(const Waypoint* waypointp);
+ void gpx_write_bounds();
+
+ QXmlStreamReader* reader;
+ xml_tag* cur_tag;
+ QString cdatastr;
+ char* opt_logpoint = nullptr;
+ char* opt_humminbirdext = nullptr;
+ char* opt_garminext = nullptr;
+ char* opt_elevation_precision = nullptr;
+ int logpoint_ct = 0;
+ int elevation_precision;
+
+// static char* gpx_version = NULL;
+ QString gpx_version;
+ char* gpx_wversion;
+ int gpx_wversion_num;
+ QXmlStreamAttributes gpx_namespace_attribute;
+
+ QString current_tag;
+
+ Waypoint* wpt_tmp;
+ UrlLink* link_;
+ UrlLink* rh_link_;
+ bool cache_descr_is_html;
+ gpsbabel::File* iqfile;
+ gpsbabel::File* oqfile;
+ gpsbabel::XmlStreamWriter* writer;
+ short_handle mkshort_handle;
+ QString link_url;
+ QString link_text;
+ QString link_type;
+
+
+ char* snlen = nullptr;
+ char* suppresswhite = nullptr;
+ char* urlbase = nullptr;
+ route_head* trk_head;
+ route_head* rte_head;
+ const route_head* current_trk_head; // Output.
+ /* used for bounds calculation on output */
+ bounds all_bounds;
+ int next_trkpt_is_new_seg;
+
+ format_specific_data** fs_ptr;
+
+ /*
+ * The file-level information.
+ * This works for gpx 1.0, but does not handle all gpx 1.1 metadata.
+ * TODO: gpx 1.1 metadata elements author, copyright, extensions,
+ * all of which have more complicated content.
+ * Note that all gpx 1.0 "global data" has a maxOccurs limit of one,
+ * which is the default if maxOccurs is not in the xsd.
+ * The only gpx 1.1 metadata that has a maxOccurs limit > one is link.
+ * However, multiple gpx files may be read, and their global/metadata
+ * combined, by this implementation.
+ */
+ struct GpxGlobal {
+ QStringList name;
+ QStringList desc;
+ QStringList author;
+ QStringList email;
+ QStringList url;
+ QStringList urlname;
+ QStringList keywords;
+ UrlList link;
+ /* time and bounds aren't here; they're recomputed. */
+ };
+ GpxGlobal* gpx_global = nullptr;
+
+ struct tag_mapping {
+ tag_type tag_type_; /* enum from above for this tag */
+ int tag_passthrough; /* true if we don't generate this */
+ const char* tag_name; /* xpath-ish tag name */
+ };
+
+ /*
+ * xpath(ish) mappings between full tag paths and internal identifiers.
+ * These appear in the order they appear in the GPX specification.
+ * If it's not a tag we explicitly handle, it doesn't go here.
+ */
+
+ /* /gpx/<name> for GPX 1.0, /gpx/metadata/<name> for GPX 1.1 */
+#define METATAG(type,name) \
+ {type, 0, "/gpx/" name}, \
+ {type, 0, "/gpx/metadata/" name}
+
+ tag_mapping tag_path_map[158] = {
+ { tt_gpx, 0, "/gpx" },
+ METATAG(tt_name, "name"),
+ METATAG(tt_desc, "desc"),
+ { tt_author, 0, "/gpx/author" },
+ { tt_email, 0, "/gpx/email" },
+ { tt_url, 0, "/gpx/url" },
+ { tt_urlname, 0, "/gpx/urlname" },
+ METATAG(tt_keywords, "keywords"),
+ { tt_link, 0, "/gpx/metadata/link" },
+ { tt_link_text, 0, "/gpx/metadata/link/text" },
+ { tt_link_type, 0, "/gpx/metadata/link/type" },
+
+ { tt_wpt, 0, "/gpx/wpt" },
+
+ /* Double up the GPX 1.0 and GPX 1.1 styles */
+#define GEOTAG(type,name) \
+ {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name }, \
+ {type, 1, "/gpx/wpt/extensions/cache/" name }, \
+ {type, 1, "/gpx/wpt/geocache/" name } /* opencaching.de */
+
+#define GARMIN_RTE_EXT "/gpx/rte/extensions/gpxx:RouteExtension"
+#define GARMIN_TRK_EXT "/gpx/trk/extensions/gpxx:TrackExtension"
+#define GARMIN_WPT_EXT "/gpx/wpt/extensions/gpxx:WaypointExtension"
+#define GARMIN_TRKPT_EXT "/gpx/trk/trkseg/trkpt/extensions/gpxtpx:TrackPointExtension"
+#define GARMIN_RTEPT_EXT "/gpx/rte/rtept/extensions/gpxxx:RoutePointExtension"
+
+// GEOTAG( tt_cache, "cache"),
+ { tt_cache, 1, "/gpx/wpt/groundspeak:cache" },
+
+ GEOTAG(tt_cache_name, "name"),
+ GEOTAG(tt_cache_container, "container"),
+ GEOTAG(tt_cache_type, "type"),
+ GEOTAG(tt_cache_difficulty, "difficulty"),
+ GEOTAG(tt_cache_terrain, "terrain"),
+ GEOTAG(tt_cache_hint, "encoded_hints"),
+ GEOTAG(tt_cache_hint, "hints"), /* opencaching.de */
+ GEOTAG(tt_cache_desc_short, "short_description"),
+ GEOTAG(tt_cache_desc_long, "long_description"),
+ GEOTAG(tt_cache_placer, "owner"),
+ GEOTAG(tt_cache_favorite_points, "favorite_points"),
+ GEOTAG(tt_cache_personal_note, "personal_note"),
+ { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"},
+ { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"},
+ { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"},
+ { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"},
+ { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"},
+ { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"},
+
+ { tt_wpt_extensions, 0, "/gpx/wpt/extensions" },
+
+ { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT },
+ { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity" },
+ { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature" },
+ { tt_garmin_wpt_temperature, 1, GARMIN_TRKPT_EXT "/gpxtpx:atemp" },
+ { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth" },
+ { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode" },
+ { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories" },
+ { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category" },
+ { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress" },
+ { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City" },
+ { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State" },
+ { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country" },
+ { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode" },
+ { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber"},
+
+ // In Garmin space, but in core of waypoint.
+ { tt_trk_trkseg_trkpt_heartrate, 1, GARMIN_TRKPT_EXT "/gpxtpx:hr" },
+ { tt_trk_trkseg_trkpt_cadence, 1, GARMIN_TRKPT_EXT "/gpxtpx:cad" },
+
+ { tt_humminbird_wpt_depth, 0, "/gpx/wpt/extensions/h:depth" }, // in centimeters.
+ { tt_humminbird_wpt_status, 0, "/gpx/wpt/extensions/h:status" },
+
+ { tt_rte, 0, "/gpx/rte" },
+ { tt_rte_name, 0, "/gpx/rte/name" },
+ { tt_rte_desc, 0, "/gpx/rte/desc" },
+ { tt_rte_url, 0, "/gpx/rte/url"}, /* GPX 1.0 */
+ { tt_rte_urlname, 0, "/gpx/rte/urlname"}, /* GPX 1.0 */
+ { tt_rte_link, 0, "/gpx/rte/link"}, /* GPX 1.1 */
+ { tt_rte_link_text, 0, "/gpx/rte/link/text"}, /* GPX 1.1 */
+ { tt_rte_link_type, 0, "/gpx/rte/link/type"}, /* GPX 1.1 */
+ { tt_rte_number, 0, "/gpx/rte/number" },
+ { tt_garmin_rte_display_color, 1, GARMIN_RTE_EXT "/gpxx:DisplayColor"},
+
+ { tt_rte_rtept, 0, "/gpx/rte/rtept" },
+
+ { tt_trk, 0, "/gpx/trk" },
+ { tt_trk_name, 0, "/gpx/trk/name" },
+ { tt_trk_desc, 0, "/gpx/trk/desc" },
+ { tt_trk_trkseg, 0, "/gpx/trk/trkseg" },
+ { tt_trk_url, 0, "/gpx/trk/url"}, /* GPX 1.0 */
+ { tt_trk_urlname, 0, "/gpx/trk/urlname"}, /* GPX 1.0 */
+ { tt_trk_link, 0, "/gpx/trk/link"}, /* GPX 1.1 */
+ { tt_trk_link_text, 0, "/gpx/trk/link/text"}, /* GPX 1.1 */
+ { tt_trk_link_type, 0, "/gpx/trk/link/type"}, /* GPX 1.1 */
+ { tt_trk_number, 0, "/gpx/trk/number" },
+ { tt_garmin_trk_display_color, 1, GARMIN_TRK_EXT "/gpxx:DisplayColor"},
+
+ { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt" },
+ { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course" },
+ { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed" },
+
+ { tt_humminbird_trk_trkseg_trkpt_depth, 0, "/gpx/trk/trkseg/trkpt/extensions/h:depth" }, // in centimeters.
+
+ /* Common to tracks, routes, and waypts */
+#define GPXWPTTYPETAG(type,passthrough,name) \
+ {type, passthrough, "/gpx/wpt/" name }, \
+ {type, passthrough, "/gpx/trk/trkseg/trkpt/" name }, \
+ {type, passthrough, "/gpx/rte/rtept/" name }
+
+ GPXWPTTYPETAG(tt_wpttype_ele, 0, "ele"),
+ GPXWPTTYPETAG(tt_wpttype_time, 0, "time"),
+ GPXWPTTYPETAG(tt_wpttype_geoidheight, 0, "geoidheight"),
+ GPXWPTTYPETAG(tt_wpttype_name, 0, "name"),
+ GPXWPTTYPETAG(tt_wpttype_cmt, 0, "cmt"),
+ GPXWPTTYPETAG(tt_wpttype_desc, 0, "desc"),
+ GPXWPTTYPETAG(tt_wpttype_url, 0, "url"), /* GPX 1.0 */
+ GPXWPTTYPETAG(tt_wpttype_urlname, 0, "urlname"), /* GPX 1.0 */
+ GPXWPTTYPETAG(tt_wpttype_link, 0, "link"), /* GPX 1.1 */
+ GPXWPTTYPETAG(tt_wpttype_link_text, 0, "link/text"), /* GPX 1.1 */
+ GPXWPTTYPETAG(tt_wpttype_link_type, 0, "link/type"), /* GPX 1.1 */
+ GPXWPTTYPETAG(tt_wpttype_sym, 0, "sym"),
+ GPXWPTTYPETAG(tt_wpttype_type, 1, "type"),
+ GPXWPTTYPETAG(tt_wpttype_fix, 0, "fix"),
+ GPXWPTTYPETAG(tt_wpttype_sat, 0, "sat"),
+ GPXWPTTYPETAG(tt_wpttype_hdop, 0, "hdop"),
+ GPXWPTTYPETAG(tt_wpttype_vdop, 0, "vdop"),
+ GPXWPTTYPETAG(tt_wpttype_pdop, 0, "pdop"),
+
+ {(tag_type)0, 0, nullptr}
+ };
+
+// Maintain a fast mapping from full tag names to the struct above.
+ QHash<QString, tag_mapping*> hash;
+
+ QVector<arglist_t> gpx_args = {
+ {
+ "snlen", &snlen, "Length of generated shortnames",
+ "32", ARGTYPE_INT, "1", nullptr, nullptr
+ },
+ {
+ "suppresswhite", &suppresswhite,
+ "No whitespace in generated shortnames",
+ nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+ },
+ {
+ "logpoint", &opt_logpoint,
+ "Create waypoints from geocache log entries",
+ nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+ },
+ {
+ "urlbase", &urlbase, "Base URL for link tag in output",
+ nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr
+ },
+ {
+ "gpxver", &gpx_wversion, "Target GPX version for output",
+ nullptr, ARGTYPE_STRING, ARG_NOMINMAX, nullptr
+ },
+ {
+ "humminbirdextensions", &opt_humminbirdext,
+ "Add info (depth) as Humminbird extension",
+ nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+ },
+ {
+ "garminextensions", &opt_garminext,
+ "Add info (depth) as Garmin extension",
+ nullptr, ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+ },
+ {
+ "elevprec", &opt_elevation_precision,
+ "Precision of elevations, number of decimals",
+ "3", ARGTYPE_INT, ARG_NOMINMAX, nullptr
+ },
+ };
+
+};
+#endif // GPX_H_INCLUDED_
--- /dev/null
+/*
+
+ Legacy format shim.
+
+ Copyright (C) 2019 Robert Lipe, robertlipe+source@gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+#ifndef LEGACYFORMAT_H_INCLUDED_
+#define LEGACYFORMAT_H_INCLUDED_
+
+#include "defs.h"
+#include "format.h"
+
+
+class LegacyFormat : public Format
+{
+public:
+ LegacyFormat() = default;
+ explicit LegacyFormat(const ff_vecs_t& v) : vec(v) {}
+
+ /*******************************************************************************
+ * %%% global callbacks called by gpsbabel main process %%% *
+ *******************************************************************************/
+
+ void rd_init(const QString& fname) override
+ {
+ if (vec.rd_init != nullptr) {
+ vec.rd_init(fname);
+ }
+ }
+
+ void rd_deinit() override
+ {
+ if (vec.rd_deinit != nullptr) {
+ vec.rd_deinit();
+ }
+ }
+
+ void read() override
+ {
+ if (vec.read != nullptr) {
+ vec.read();
+ }
+ }
+
+ void wr_init(const QString& fname) override
+ {
+ if (vec.wr_init != nullptr) {
+ vec.wr_init(fname);
+ }
+ }
+
+ void wr_deinit() override
+ {
+ if (vec.wr_deinit != nullptr) {
+ vec.wr_deinit();
+ }
+ }
+
+ void write() override
+ {
+ if (vec.write != nullptr) {
+ vec.write();
+ }
+ }
+
+ void exit() override
+ {
+ if (vec.exit != nullptr) {
+ vec.exit();
+ }
+ }
+
+ void rd_position_init(const QString& fname) override
+ {
+ if (vec.position_ops.rd_init != nullptr) {
+ vec.position_ops.rd_init(fname);
+ }
+ }
+
+ Waypoint* rd_position(posn_status* status) override
+ {
+ if (vec.position_ops.rd_position != nullptr) {
+ return vec.position_ops.rd_position(status);
+ }
+ return nullptr;
+ }
+
+ void rd_position_deinit() override
+ {
+ if (vec.position_ops.rd_deinit != nullptr) {
+ vec.position_ops.rd_deinit();
+ }
+ }
+
+ void wr_position_init(const QString& fname) override
+ {
+ if (vec.position_ops.wr_init != nullptr) {
+ vec.position_ops.wr_init(fname);
+ }
+ }
+
+ void wr_position(Waypoint* wpt) override
+ {
+ if (vec.position_ops.wr_position != nullptr) {
+ vec.position_ops.wr_position(wpt);
+ }
+ }
+
+ void wr_position_deinit() override
+ {
+ if (vec.position_ops.wr_deinit != nullptr) {
+ vec.position_ops.wr_deinit();
+ }
+ }
+
+ /*******************************************************************************
+ * %%% Accessors %%% *
+ *******************************************************************************/
+
+ QVector<arglist_t>* get_args() override
+ {
+ return vec.args;
+ }
+
+ ff_type get_type() const override
+ {
+ return vec.type;
+ }
+
+ QVector<ff_cap> get_cap() const override
+ {
+ return vec.cap;
+ }
+ QString get_encode() const override
+ {
+ return vec.encode;
+ }
+
+ int get_fixed_encode() const override
+ {
+ return vec.fixed_encode;
+ }
+
+private:
+ ff_vecs_t vec;
+
+};
+#endif // LEGACYFORMAT_H_INCLUDED_
#include "defs.h"
#include "explorist_ini.h" // for explorist_ini_done, explorist_ini_get, mag_info
+#include "format.h" // for Format
#include "gbfile.h" // for gbfclose, gbfeof, gbfgets, gbfopen, gbfwrite, gbfile
#include "gbser.h" // for gbser_deinit, gbser_init, gbser_is_serial, gbser_read_line, gbser_set_port, gbser_write, gbser_OK
#include "magellan.h" // for mm_meridian, mm_sportrak, magellan_icon_mapping_t, mm_gps315320, mm_unknown, mm_map330, mm_map410, pid_to_model_t, mm_gps310, m330_cleanse, mag_checksum, mag_find_descr_from_token, mag_find_token_from_descr, mag_rteparse, mag_trkparse
#include "src/core/datetime.h" // for DateTime
+#include "vecs.h" // for Vecs
static int bitrate = 4800;
static int extension_hint;
// For Explorist GC/510/610/710 families, bludgeon in GPX support.
// (This has nothing to do with the Explorist 100...600 products.)
-static ff_vecs_t* gpx_vec;
+static Format* gpx_vec;
static mag_info* explorist_info;
static QStringList os_gpx_files(const char* dirname);
const char** dlist = os_get_magellan_mountpoints();
explorist_info = explorist_ini_get(dlist);
if (explorist_info) {
- gpx_vec = find_vec("gpx");
+ gpx_vec = Vecs::Instance().find_vec("gpx");
}
return;
}
#include <cstdio> // for printf, fgetc, stdin
#include <cstdlib> // for exit
#include <cstring> // for strcmp
-#include <ctime> // for time
#include <QtCore/QByteArray> // for QByteArray
#include <QtCore/QChar> // for QChar
#include "cet_util.h" // for cet_convert_init, cet_convert_strings, cet_convert_deinit, cet_deregister, cet_register, cet_cs_vec_utf8
#include "csv_util.h" // for csv_linesplit
#include "filter.h" // for Filter
-#include "filterdefs.h" // for disp_filter_vec, disp_filter_vecs, disp_filters, exit_filter_vecs, find_filter_vec, free_filter_vec, init_filter_vecs
+#include "filter_vecs.h" // for FilterVecs
+#include "format.h" // for Format
#include "inifile.h" // for inifile_done, inifile_init
#include "session.h" // for start_session, session_exit, session_init
#include "src/core/datetime.h" // for DateTime
#include "src/core/file.h" // for File
#include "src/core/usasciicodec.h" // for UsAsciiCodec
+#include "vecs.h" // for Vecs
#define MYNAME "main"
// be careful not to advance argn passed the end of the list, i.e. ensure argn < qargs.size()
fgetc(stdin);
} else {
printf("File Types (-i and -o options):\n");
- disp_vecs();
+ Vecs::Instance().disp_vecs();
printf("\nSupported data filters:\n");
- disp_filter_vecs();
+ FilterVecs::Instance().disp_filter_vecs();
}
}
spec_usage(const QString& vec)
{
printf("\n");
- disp_vec(vec);
- disp_filter_vec(vec);
+ Vecs::Instance().disp_vec(vec);
+ FilterVecs::Instance().disp_filter_vec(vec);
printf("\n");
}
run(const char* prog_name)
{
int argn;
- ff_vecs_t* ivecs = nullptr;
- ff_vecs_t* ovecs = nullptr;
+ Format* ivecs = nullptr;
+ Format* ovecs = nullptr;
Filter* filter = nullptr;
QString fname;
QString ofname;
switch (c) {
case 'i':
optarg = FETCH_OPTARG;
- ivecs = find_vec(optarg);
+ ivecs = Vecs::Instance().find_vec(optarg);
if (ivecs == nullptr) {
fatal("Input type '%s' not recognized\n", qPrintable(optarg));
}
warning("-o appeared before -i. This is probably not what you want to do.\n");
}
optarg = FETCH_OPTARG;
- ovecs = find_vec(optarg);
+ ovecs = Vecs::Instance().find_vec(optarg);
if (ovecs == nullptr) {
fatal("Output type '%s' not recognized\n", qPrintable(optarg));
}
if (ivecs == nullptr) {
fatal("No valid input type specified\n");
}
- if (ivecs->rd_init == nullptr) {
- fatal("Format does not support reading.\n");
- }
if (global_opts.masked_objective & POSNDATAMASK) {
did_something = true;
break;
global_opts.masked_objective |= WPTDATAMASK;
}
- cet_convert_init(ivecs->encode, ivecs->fixed_encode); /* init by module vec */
+ cet_convert_init(ivecs->get_encode(), ivecs->get_fixed_encode()); /* init by module vec */
- start_session(ivecs->name, fname);
+ start_session(ivecs->get_name(), fname);
ivecs->rd_init(fname);
ivecs->read();
ivecs->rd_deinit();
if (doing_nothing) {
global_opts.masked_objective |= WPTDATAMASK;
}
- if (ovecs->wr_init == nullptr) {
- fatal("Format does not support writing.\n");
- }
- cet_convert_init(ovecs->encode, ovecs->fixed_encode);
+ cet_convert_init(ovecs->get_encode(), ovecs->get_fixed_encode());
lists_backedup = false;
wpt_head_bak = nullptr;
if (global_opts.charset != &cet_cs_vec_utf8) {
/*
* Push and pop verbose_status so
- * we don't get dual progress bars
+ * we don't get dual progress bars
* when doing characterset
* transformation.
*/
break;
case 'x':
optarg = FETCH_OPTARG;
- filter = find_filter_vec(optarg);
+ filter = FilterVecs::Instance().find_filter_vec(optarg);
if (filter) {
filter->init();
filter->process();
filter->deinit();
- free_filter_vec(filter);
+ FilterVecs::free_filter_vec(filter);
} else {
fatal("Unknown filter '%s'\n",qPrintable(optarg));
}
* Undocumented '-@' option for test.
*/
case '@': {
- bool format_ok = validate_formats();
- bool filter_ok = validate_filters();
+ bool format_ok = Vecs::Instance().validate_formats();
+ bool filter_ok = FilterVecs::Instance().validate_filters();
return (format_ok && filter_ok)? 0 : 1;
}
* this as -^^.
*/
case '^':
- disp_formats(opt_version);
+ Vecs::Instance().disp_formats(opt_version);
return 0;
case '%':
- disp_filters(opt_version);
+ FilterVecs::Instance().disp_filters(opt_version);
return 0;
case 'h':
case '?':
global_opts.masked_objective |= WPTDATAMASK;
}
- cet_convert_init(ivecs->encode, 1);
+ cet_convert_init(ivecs->get_encode(), 1);
- start_session(ivecs->name, qargs.at(0));
- if (ivecs->rd_init == nullptr) {
- fatal("Format does not support reading.\n");
- }
+ start_session(ivecs->get_name(), qargs.at(0));
ivecs->rd_init(qargs.at(0));
ivecs->read();
ivecs->rd_deinit();
cet_convert_deinit();
if (qargs.size() == 2 && ovecs) {
- cet_convert_init(ovecs->encode, 1);
+ cet_convert_init(ovecs->get_encode(), 1);
cet_convert_strings(nullptr, global_opts.charset);
- if (ovecs->wr_init == nullptr) {
- fatal("Format does not support writing.\n");
- }
-
ovecs->wr_init(qargs.at(1));
ovecs->write();
ovecs->wr_deinit();
fatal("Realtime tracking (-T) requires an input type (-t)i such as Garmin or NMEA.\n");
}
- if (!ivecs->position_ops.rd_position) {
- fatal("Realtime tracking (-T) is not suppored by this input type.\n");
- }
-
-
- if (ivecs->position_ops.rd_init) {
- if (fname.isEmpty()) {
- fatal("An input file (-f) must be specified.\n");
- }
- start_session(ivecs->name, fname);
- ivecs->position_ops.rd_init(fname);
+ if (fname.isEmpty()) {
+ fatal("An input file (-f) must be specified.\n");
}
+ start_session(ivecs->get_name(), fname);
+ ivecs->rd_position_init(fname);
if (global_opts.masked_objective & ~POSNDATAMASK) {
fatal("Realtime tracking (-T) is exclusive of other modes.\n");
}
- if (ovecs) {
- if (!ovecs->position_ops.wr_position) {
- fatal("This output format does not support output of realtime positioning.\n");
- }
- }
-
if (signal(SIGINT, signal_handler) == SIG_ERR) {
fatal("Couldn't install the exit signal handler.\n");
}
- if (ovecs && ovecs->position_ops.wr_init) {
- ovecs->position_ops.wr_init(ofname);
+ if (ovecs) {
+ ovecs->wr_position_init(ofname);
}
tracking_status.request_terminate = 0;
while (!tracking_status.request_terminate) {
- Waypoint* wpt = ivecs->position_ops.rd_position(&tracking_status);
+ Waypoint* wpt = ivecs->rd_position(&tracking_status);
if (tracking_status.request_terminate) {
delete wpt;
}
if (wpt) {
if (ovecs) {
-// ovecs->position_ops.wr_init(ofname);
- ovecs->position_ops.wr_position(wpt);
-// ovecs->position_ops.wr_deinit();
+// ovecs->wr_position_init(ofname);
+ ovecs->wr_position(wpt);
+// ovecs->wr_position_deinit();
} else {
/* Just print to screen */
waypt_disp(wpt);
delete wpt;
}
}
- if (ivecs->position_ops.rd_deinit) {
- ivecs->position_ops.rd_deinit();
- }
- if (ovecs && ovecs->position_ops.wr_deinit) {
- ovecs->position_ops.wr_deinit();
+ ivecs->rd_position_deinit();
+ if (ovecs) {
+ ovecs->wr_position_deinit();
}
return 0;
}
global_opts.inifile = inifile_init(QString(), MYNAME);
}
- init_vecs();
- init_filter_vecs();
+ Vecs::Instance().init_vecs();
+ FilterVecs::Instance().init_filter_vecs();
cet_register();
session_init();
waypt_init();
waypt_flush_all();
route_deinit();
session_exit();
- exit_vecs();
- exit_filter_vecs();
+ Vecs::Instance().exit_vecs();
+ FilterVecs::Instance().exit_filter_vecs();
inifile_done(global_opts.inifile);
exit(rc);
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#ifndef REVERSE_ROUTE_H_INCLUDED_
+#define REVERSE_ROUTE_H_INCLUDED_
#include <QtCore/QVector> // for QVector
};
#endif
+#endif // REVERSE_ROUTE_H_INCLUDED_
#include <cassert> // for assert
#include <cctype> // for isdigit
#include <cstdio> // for printf, putchar, sscanf, size_t
-#include <cstdint>
-#include <cstring> // for strchr, strtok, memset, strlen
#include "defs.h"
+#include "vecs.h"
+#include "format.h"
#include "gbversion.h" // for WEB_DOC_DIR
#include "inifile.h" // for inifile_readstr
+#include "legacyformat.h"
#include "src/core/logging.h" // for Warning
#include "xcsv.h" // for XcsvFile, xcsv_file, xcsv_read_internal_style, xcsv_setup_internal_style
#define MYNAME "vecs"
-struct vecs_t {
- ff_vecs_t* vec;
- QString name;
- QString desc;
- QString extensions; // list of possible extensions separated by '/', first is output default for GUI.
- QString parent;
-};
-
-extern ff_vecs_t an1_vecs;
-extern ff_vecs_t bcr_vecs;
-extern ff_vecs_t brauniger_iq_vecs;
-extern ff_vecs_t cetus_vecs;
-extern ff_vecs_t compegps_vecs;
-extern ff_vecs_t copilot_vecs;
-extern ff_vecs_t coto_vecs;
-extern ff_vecs_t cst_vecs;
-extern ff_vecs_t dg100_vecs;
-extern ff_vecs_t dg200_vecs;
-extern ff_vecs_t easygps_vecs;
-extern ff_vecs_t energympro_vecs;
-extern ff_vecs_t garmin_vecs;
-extern ff_vecs_t garmin_txt_vecs;
-extern ff_vecs_t gcdb_vecs;
-extern ff_vecs_t gdb_vecs;
-extern ff_vecs_t geoniche_vecs;
-extern ff_vecs_t geo_vecs;
-extern ff_vecs_t geojson_vecs;
-extern ff_vecs_t globalsat_sport_vecs;
-extern ff_vecs_t glogbook_vecs;
-extern ff_vecs_t google_dir_vecs;
-extern ff_vecs_t gpilots_vecs;
-extern ff_vecs_t gpl_vecs;
-extern ff_vecs_t gpssim_vecs;
-extern ff_vecs_t gpspilot_vecs;
-extern ff_vecs_t gpsutil_vecs;
-extern ff_vecs_t gpx_vecs;
-extern ff_vecs_t gtm_vecs;
-extern ff_vecs_t hiketech_vecs;
-extern ff_vecs_t holux_vecs;
-extern ff_vecs_t HsaEndeavourNavigator_vecs;
-extern ff_vecs_t html_vecs;
-extern ff_vecs_t igc_vecs;
-extern ff_vecs_t ignr_vecs;
-extern ff_vecs_t igo8_vecs;
-extern ff_vecs_t kml_vecs;
-extern ff_vecs_t lowranceusr_vecs;
-extern ff_vecs_t mag_fvecs;
-extern ff_vecs_t maggeo_vecs;
-extern ff_vecs_t magnav_vec;
-extern ff_vecs_t mag_svecs;
-extern ff_vecs_t magX_fvecs;
-extern ff_vecs_t mapsend_vecs;
-extern ff_vecs_t mps_vecs;
-extern ff_vecs_t mtk_vecs;
-extern ff_vecs_t mtk_fvecs;
-extern ff_vecs_t mtk_m241_vecs;
-extern ff_vecs_t mtk_m241_fvecs;
-extern ff_vecs_t mtk_locus_vecs;
-extern ff_vecs_t mynav_vecs;
-extern ff_vecs_t navicache_vecs;
-extern ff_vecs_t netstumbler_vecs;
-extern ff_vecs_t nmea_vecs;
-extern ff_vecs_t nmn4_vecs;
-extern ff_vecs_t ozi_vecs;
-extern ff_vecs_t palmdoc_vecs;
-extern ff_vecs_t pcx_vecs;
-extern ff_vecs_t psit_vecs; /* MRCB */
-extern ff_vecs_t quovadis_vecs;
-extern ff_vecs_t saroute_vecs;
-extern ff_vecs_t shape_vecs;
-extern ff_vecs_t skytraq_vecs;
-extern ff_vecs_t skytraq_fvecs;
-extern ff_vecs_t miniHomer_vecs;
-#if CSVFMTS_ENABLED
-extern ff_vecs_t stmsdf_vecs;
-#endif
-#if CSVFMTS_ENABLED
-extern ff_vecs_t stmwpp_vecs;
-#endif
-extern ff_vecs_t tef_xml_vecs;
-extern ff_vecs_t text_vecs;
-extern ff_vecs_t tiger_vecs;
-extern ff_vecs_t tmpro_vecs;
-extern ff_vecs_t tomtom_vecs;
-extern ff_vecs_t tpg_vecs;
-extern ff_vecs_t tpo2_vecs;
-extern ff_vecs_t tpo3_vecs;
-extern ff_vecs_t unicsv_vecs;
-extern ff_vecs_t vcf_vecs;
-extern ff_vecs_t vitosmt_vecs;
-extern ff_vecs_t wfff_xml_vecs;
-extern ff_vecs_t xcsv_vecs;
-extern ff_vecs_t yahoo_vecs;
-extern ff_vecs_t wbt_svecs;
-extern ff_vecs_t wbt_fvecs;
-extern ff_vecs_t gtc_vecs;
-extern ff_vecs_t dmtlog_vecs;
-extern ff_vecs_t raymarine_vecs;
-extern ff_vecs_t alanwpr_vecs;
-extern ff_vecs_t alantrl_vecs;
-extern ff_vecs_t vitovtt_vecs;
-extern ff_vecs_t ggv_bin_vecs;
-extern ff_vecs_t ggv_log_vecs;
-extern ff_vecs_t g7towin_vecs;
-extern ff_vecs_t garmin_gpi_vecs;
-extern ff_vecs_t lmx_vecs;
-extern ff_vecs_t random_vecs;
-extern ff_vecs_t xol_vecs;
-extern ff_vecs_t navilink_vecs;
-extern ff_vecs_t ik3d_vecs;
-extern ff_vecs_t osm_vecs;
-extern ff_vecs_t destinator_poi_vecs;
-extern ff_vecs_t destinator_trl_vecs;
-extern ff_vecs_t destinator_itn_vecs;
-extern ff_vecs_t exif_vecs;
-extern ff_vecs_t vidaone_vecs;
-extern ff_vecs_t gopal_vecs;
-extern ff_vecs_t humminbird_vecs;
-extern ff_vecs_t humminbird_ht_vecs;
-extern ff_vecs_t mapasia_tr7_vecs;
-extern ff_vecs_t gnav_trl_vecs;
-extern ff_vecs_t navitel_trk_vecs;
-extern ff_vecs_t ggv_ovl_vecs;
-#if CSVFMTS_ENABLED
-extern ff_vecs_t jtr_vecs;
-#endif
-extern ff_vecs_t itracku_vecs;
-extern ff_vecs_t itracku_fvecs;
-extern ff_vecs_t sbp_vecs;
-extern ff_vecs_t ng_vecs;
-extern ff_vecs_t sbn_vecs;
-extern ff_vecs_t mmo_vecs;
-extern ff_vecs_t bushnell_vecs;
-extern ff_vecs_t bushnell_trl_vecs;
-extern ff_vecs_t skyforce_vecs;
-extern ff_vecs_t v900_vecs;
-extern ff_vecs_t pocketfms_bc_vecs;
-extern ff_vecs_t pocketfms_fp_vecs;
-extern ff_vecs_t pocketfms_wp_vecs;
-extern ff_vecs_t enigma_vecs;
-extern ff_vecs_t vpl_vecs;
-extern ff_vecs_t teletype_vecs;
-extern ff_vecs_t jogmap_vecs;
-extern ff_vecs_t wintec_tes_vecs;
-extern ff_vecs_t subrip_vecs;
-extern ff_vecs_t format_garmin_xt_vecs;
-extern ff_vecs_t format_fit_vecs;
-extern ff_vecs_t mapbar_track_vecs;
-extern ff_vecs_t f90g_track_vecs;
-extern ff_vecs_t mapfactor_vecs;
-
-static
-const QVector<vecs_t> vec_list = {
-#if CSVFMTS_ENABLED
- /* XCSV must be the first entry in this table. */
- {
- &xcsv_vecs,
- "xcsv",
- "? Character Separated Values",
- nullptr,
- nullptr,
- },
-#endif
- {
- &geo_vecs,
- "geo",
- "Geocaching.com .loc",
- "loc",
- nullptr,
- },
- {
- &gpx_vecs,
- "gpx",
- "GPX XML",
- "gpx",
- nullptr,
- },
- {
- &mag_svecs,
- "magellan",
- "Magellan serial protocol",
- nullptr,
- nullptr,
- },
- {
- &mag_fvecs,
- "magellan",
- "Magellan SD files (as for Meridian)",
- nullptr,
- nullptr,
- },
- {
- &magX_fvecs,
- "magellanx",
- "Magellan SD files (as for eXplorist)",
- "upt",
- nullptr,
- },
- {
- &garmin_vecs,
- "garmin",
- "Garmin serial/USB protocol",
- nullptr,
- nullptr,
- },
- {
- &gdb_vecs,
- "gdb",
- "Garmin MapSource - gdb",
- "gdb",
- nullptr,
- },
- {
- &mapsend_vecs,
- "mapsend",
- "Magellan Mapsend",
- nullptr,
- nullptr,
- },
- {
- &mps_vecs,
- "mapsource",
- "Garmin MapSource - mps",
- "mps",
- nullptr,
- },
- {
- &nmea_vecs,
- "nmea",
- "NMEA 0183 sentences",
- nullptr,
- nullptr,
- },
- {
- &ozi_vecs,
- "ozi",
- "OziExplorer",
- nullptr,
- nullptr,
- },
- {
- &pcx_vecs,
- "pcx",
- "Garmin PCX5",
- "pcx",
- nullptr,
- },
- {
- &kml_vecs,
- "kml",
- "Google Earth (Keyhole) Markup Language",
- "kml",
- nullptr,
- },
-#if MAXIMAL_ENABLED
- {
- &gpsutil_vecs,
- "gpsutil",
- "gpsutil",
- nullptr,
- nullptr,
- },
- {
- &lowranceusr_vecs,
- "lowranceusr",
- "Lowrance USR",
- "usr",
- nullptr,
- },
- {
- &holux_vecs,
- "holux",
- "Holux (gm-100) .wpo Format",
- "wpo",
- nullptr,
- },
- {
- &tpg_vecs,
- "tpg",
- "National Geographic Topo .tpg (waypoints)",
- "tpg",
- nullptr,
- },
- {
- &tpo2_vecs,
- "tpo2",
- "National Geographic Topo 2.x .tpo",
- "tpo",
- nullptr,
- },
- {
- &tpo3_vecs,
- "tpo3",
- "National Geographic Topo 3.x/4.x .tpo",
- "tpo",
- nullptr,
- },
- {
- &tmpro_vecs,
- "tmpro",
- "TopoMapPro Places File",
- "tmpro",
- nullptr,
- },
- {
- &tiger_vecs,
- "tiger",
- "U.S. Census Bureau Tiger Mapping Service",
- nullptr,
- nullptr,
- },
- {
- &easygps_vecs,
- "easygps",
- "EasyGPS binary format",
- "loc",
- nullptr,
- },
- {
- &saroute_vecs,
- "saroute",
- "DeLorme Street Atlas Route",
- "anr",
- nullptr,
- },
- {
- &navicache_vecs,
- "navicache",
- "Navicache.com XML",
- nullptr,
- nullptr,
- },
- { /* MRCB */
- &psit_vecs,
- "psitrex",
- "KuDaTa PsiTrex text",
- nullptr,
- nullptr,
- },
-#if SHAPELIB_ENABLED
- {
- &shape_vecs,
- "shape",
- "ESRI shapefile",
- "shp",
- nullptr,
- },
-#endif
- {
- &gpl_vecs,
- "gpl",
- "DeLorme GPL",
- "gpl",
- nullptr,
- },
- {
- &text_vecs,
- "text",
- "Textual Output",
- "txt",
- nullptr,
- },
- {
- &html_vecs,
- "html",
- "HTML Output",
- "html",
- nullptr,
- },
- {
- &netstumbler_vecs,
- "netstumbler",
- "NetStumbler Summary File (text)",
- nullptr,
- nullptr,
- },
- {
- &igc_vecs,
- "igc",
- "FAI/IGC Flight Recorder Data Format",
- nullptr,
- nullptr,
- },
- {
- &brauniger_iq_vecs,
- "baroiq",
- "Brauniger IQ Series Barograph Download",
- nullptr,
- nullptr,
- },
- {
- &mtk_vecs,
- "mtk",
- "MTK Logger (iBlue 747,Qstarz BT-1000,...) download",
- nullptr,
- nullptr,
- },
- {
- &mtk_fvecs,
- "mtk-bin",
- "MTK Logger (iBlue 747,...) Binary File Format",
- "bin",
- nullptr,
- },
- {
- &mtk_m241_vecs,
- "m241",
- "Holux M-241 (MTK based) download",
- nullptr,
- nullptr,
- },
- {
- &mtk_m241_fvecs,
- "m241-bin",
- "Holux M-241 (MTK based) Binary File Format",
- "bin",
- nullptr,
- },
- {
- &mtk_locus_vecs,
- "mtk_locus",
- "MediaTek Locus",
- nullptr,
- nullptr,
- },
-#endif // MAXIMAL_ENABLED
- {
- &wbt_svecs,
- "wbt",
- "Wintec WBT-100/200 GPS Download",
- nullptr,
- nullptr,
- },
-#if MAXIMAL_ENABLED
- {
- &vpl_vecs,
- "vpl",
- "Honda/Acura Navigation System VP Log File Format",
- nullptr,
- nullptr,
- },
- {
- &wbt_fvecs,
- "wbt-bin",
- "Wintec WBT-100/200 Binary File Format",
- "bin",
- nullptr,
- },
- {
- &wbt_fvecs,
- "wbt-tk1",
- "Wintec WBT-201/G-Rays 2 Binary File Format",
- "tk1",
- nullptr,
- },
- {
- &hiketech_vecs,
- "hiketech",
- "HikeTech",
- "gps",
- nullptr,
- },
- {
- &glogbook_vecs,
- "glogbook",
- "Garmin Logbook XML",
- "xml",
- nullptr,
- },
- {
- &vcf_vecs,
- "vcard",
- "Vcard Output (for iPod)",
- "vcf",
- nullptr,
- },
- {
- &google_dir_vecs,
- "googledir",
- "Google Directions XML",
- "xml",
- nullptr,
- },
- {
- &maggeo_vecs,
- "maggeo",
- "Magellan Explorist Geocaching",
- "gs",
- nullptr,
- },
- {
- &an1_vecs,
- "an1",
- "DeLorme .an1 (drawing) file",
- "an1",
- nullptr,
- },
- {
- &tomtom_vecs,
- "tomtom",
- "TomTom POI file (.ov2)",
- "ov2",
- nullptr,
- },
- {
- &tef_xml_vecs,
- "tef",
- "Map&Guide 'TourExchangeFormat' XML",
- "xml",
- nullptr,
- },
- {
- &vitosmt_vecs,
- "vitosmt",
- "Vito Navigator II tracks",
- "smt",
- nullptr,
- },
- {
- &wfff_xml_vecs,
- "wfff",
- "WiFiFoFum 2.0 for PocketPC XML",
- "xml",
- nullptr,
- },
- {
- &bcr_vecs,
- "bcr",
- "Motorrad Routenplaner (Map&Guide) .bcr files",
- "bcr",
- nullptr,
- },
- {
- &ignr_vecs,
- "ignrando",
- "IGN Rando track files",
- "rdn",
- nullptr,
- },
-#if CSVFMTS_ENABLED
- {
- &stmsdf_vecs,
- "stmsdf",
- "Suunto Trek Manager (STM) .sdf files",
- "sdf",
- nullptr,
- },
-#endif
-#if CSVFMTS_ENABLED
- {
- &stmwpp_vecs,
- "stmwpp",
- "Suunto Trek Manager (STM) WaypointPlus files",
- "txt",
- nullptr,
- },
-#endif // CSVFMTS_ENABLED
- {
- &cst_vecs,
- "cst",
- "CarteSurTable data file",
- "cst",
- nullptr,
- },
- {
- &nmn4_vecs,
- "nmn4",
- "Navigon Mobile Navigator .rte files",
- "rte",
- nullptr,
- },
-#if CSVFMTS_ENABLED
- {
- &compegps_vecs,
- "compegps",
- "CompeGPS data files (.wpt/.trk/.rte)",
- nullptr,
- nullptr,
- },
-#endif //CSVFMTS_ENABLED
- {
- &yahoo_vecs,
- "yahoo",
- "Yahoo Geocode API data",
- nullptr,
- nullptr,
- },
- {
- &unicsv_vecs,
- "unicsv",
- "Universal csv with field structure in first line",
- nullptr,
- nullptr,
- },
- {
- >m_vecs,
- "gtm",
- "GPS TrackMaker",
- "gtm",
- nullptr,
- },
- {
- &gpssim_vecs,
- "gpssim",
- "Franson GPSGate Simulation",
- "gpssim",
- nullptr,
- },
-#if CSVFMTS_ENABLED
- {
- &garmin_txt_vecs,
- "garmin_txt",
- "Garmin MapSource - txt (tab delimited)",
- "txt",
- nullptr,
- },
-#endif // CSVFMTS_ENABLED
- {
- >c_vecs,
- "gtrnctr",
- "Garmin Training Center (.tcx/.crs/.hst/.xml)",
- "tcx/crs/hst/xml",
- nullptr,
- },
- {
- &dmtlog_vecs,
- "dmtlog",
- "TrackLogs digital mapping (.trl)",
- "trl",
- nullptr,
- },
- {
- &raymarine_vecs,
- "raymarine",
- "Raymarine Waypoint File (.rwf)",
- "rwf",
- nullptr,
- },
- {
- &alanwpr_vecs,
- "alanwpr",
- "Alan Map500 waypoints and routes (.wpr)",
- "wpr",
- nullptr,
- },
- {
- &alantrl_vecs,
- "alantrl",
- "Alan Map500 tracklogs (.trl)",
- "trl",
- nullptr,
- },
- {
- &vitovtt_vecs,
- "vitovtt",
- "Vito SmartMap tracks (.vtt)",
- "vtt",
- nullptr,
- },
- {
- &ggv_log_vecs,
- "ggv_log",
- "Geogrid-Viewer tracklogs (.log)",
- "log",
- nullptr,
- },
-#if CSVFMTS_ENABLED
- {
- &g7towin_vecs,
- "g7towin",
- "G7ToWin data files (.g7t)",
- "g7t",
- nullptr,
- },
-#endif
- {
- &garmin_gpi_vecs,
- "garmin_gpi",
- "Garmin Points of Interest (.gpi)",
- "gpi",
- nullptr,
- },
- {
- &lmx_vecs,
- "lmx",
- "Nokia Landmark Exchange",
- nullptr,
- nullptr,
- },
- {
- &random_vecs,
- "random",
- "Internal GPS data generator",
- nullptr,
- nullptr,
- },
- {
- &xol_vecs,
- "xol",
- "Swiss Map 25/50/100 (.xol)",
- "xol",
- nullptr,
- },
- {
- &dg100_vecs,
- "dg-100",
- "GlobalSat DG-100/BT-335 Download",
- nullptr,
- nullptr,
- },
- {
- &dg200_vecs,
- "dg-200",
- "GlobalSat DG-200 Download",
- nullptr,
- nullptr,
- },
- {
- &navilink_vecs,
- "navilink",
- "NaviGPS GT-11/BGT-11 Download",
- nullptr,
- nullptr,
- },
- {
- &ik3d_vecs,
- "ik3d",
- "MagicMaps IK3D project file (.ikt)",
- "ikt",
- nullptr,
- },
- {
- &osm_vecs,
- "osm",
- "OpenStreetMap data files",
- "osm",
- nullptr,
- },
- {
- &destinator_poi_vecs,
- "destinator_poi",
- "Destinator Points of Interest (.dat)",
- "dat",
- nullptr,
- },
- {
- &destinator_itn_vecs,
- "destinator_itn",
- "Destinator Itineraries (.dat)",
- "dat",
- nullptr,
- },
- {
- &destinator_trl_vecs,
- "destinator_trl",
- "Destinator TrackLogs (.dat)",
- "dat",
- nullptr,
- },
- {
- &exif_vecs,
- "exif",
- "Embedded Exif-GPS data (.jpg)",
- "jpg",
- nullptr,
- },
- {
- &vidaone_vecs,
- "vidaone",
- "VidaOne GPS for Pocket PC (.gpb)",
- "gpb",
- nullptr,
- },
- {
- &igo8_vecs,
- "igo8",
- "IGO8 .trk",
- "trk",
- nullptr,
- },
- {
- &gopal_vecs,
- "gopal",
- "GoPal GPS track log (.trk)",
- "trk",
- nullptr,
- },
- {
- &humminbird_vecs,
- "humminbird",
- "Humminbird waypoints and routes (.hwr)",
- "hwr",
- nullptr,
- },
- {
- &humminbird_ht_vecs,
- "humminbird_ht",
- "Humminbird tracks (.ht)",
- "ht",
- nullptr,
- },
- {
- &mapasia_tr7_vecs,
- "mapasia_tr7",
- "MapAsia track file (.tr7)",
- "tr7",
- nullptr,
- },
- {
- &gnav_trl_vecs,
- "gnav_trl",
- "Google Navigator Tracklines (.trl)",
- "trl",
- nullptr,
- },
- {
- &navitel_trk_vecs,
- "navitel_trk",
- "Navitel binary track (.bin)",
- "bin",
- nullptr,
- },
- {
- &ggv_ovl_vecs,
- "ggv_ovl",
- "Geogrid-Viewer ascii overlay file (.ovl)",
- "ovl",
- nullptr,
- },
-#if CSVFMTS_ENABLED
- {
- &jtr_vecs,
- "jtr",
- "Jelbert GeoTagger data file",
- "jtr",
- nullptr,
- },
-#endif
- {
- &itracku_vecs,
- "itracku",
- "XAiOX iTrackU Logger",
- nullptr,
- nullptr,
- },
-
- {
- &itracku_fvecs,
- "itracku-bin",
- "XAiOX iTrackU Logger Binary File Format",
- "bin",
- nullptr,
- },
- {
- &sbp_vecs,
- "sbp",
- "NaviGPS GT-31/BGT-31 datalogger (.sbp)",
- "sbp",
- nullptr,
- },
- {
- &sbn_vecs,
- "sbn",
- "NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)",
- "sbn",
- nullptr,
- },
- {
- &mmo_vecs,
- "mmo",
- "Memory-Map Navigator overlay files (.mmo)",
- "mmo",
- nullptr,
- },
- {
- &bushnell_vecs,
- "bushnell",
- "Bushnell GPS Waypoint file",
- "wpt",
- nullptr,
- },
- {
- &bushnell_trl_vecs,
- "bushnell_trl",
- "Bushnell GPS Trail file",
- "trl",
- nullptr,
- },
- {
- &skyforce_vecs,
- "skyforce",
- "Skymap / KMD150 ascii files",
- nullptr,
- nullptr,
- },
- {
- &pocketfms_bc_vecs,
- "pocketfms_bc",
- "PocketFMS breadcrumbs",
- nullptr,
- nullptr,
- },
- {
- &pocketfms_fp_vecs,
- "pocketfms_fp",
- "PocketFMS flightplan (.xml)",
- "xml",
- nullptr,
- },
- {
- &pocketfms_wp_vecs,
- "pocketfms_wp",
- "PocketFMS waypoints (.txt)",
- "txt",
- nullptr,
- },
- {
- &v900_vecs,
- "v900",
- "Columbus/Visiontac V900 files (.csv)",
- nullptr,
- nullptr,
- },
- {
- &ng_vecs,
- "naviguide",
- "Naviguide binary route file (.twl)",
- "twl",
- nullptr,
- },
- {
- &enigma_vecs,
- "enigma",
- "Enigma binary waypoint file (.ert)",
- "ert",
- nullptr,
- },
- {
- &skytraq_vecs,
- "skytraq",
- "SkyTraq Venus based loggers (download)",
- nullptr,
- nullptr,
- },
- {
- &teletype_vecs,
- "teletype",
- "Teletype [ Get Jonathon Johnson to describe",
- nullptr,
- nullptr,
- },
- {
- &skytraq_fvecs,
- "skytraq-bin",
- "SkyTraq Venus based loggers Binary File Format",
- "bin",
- nullptr,
- },
- {
- &miniHomer_vecs,
- "miniHomer",
- "MiniHomer, a skyTraq Venus 6 based logger (download tracks, waypoints and get/set POI)",
- nullptr,
- nullptr,
- },
- {
- &jogmap_vecs,
- "jogmap",
- "Jogmap.de XML format",
- "xml",
- nullptr,
- },
- {
- &wintec_tes_vecs,
- "wintec_tes",
- "Wintec TES file",
- "tes",
- nullptr,
- },
- {
- &subrip_vecs,
- "subrip",
- "SubRip subtitles for video mapping (.srt)",
- "srt",
- nullptr,
- },
- {
- &format_garmin_xt_vecs,
- "garmin_xt",
- "Mobile Garmin XT Track files",
- nullptr,
- nullptr,
- },
- {
- &format_fit_vecs,
- "garmin_fit",
- "Flexible and Interoperable Data Transfer (FIT) Activity file",
- "fit",
- nullptr,
- },
- {
- &mapbar_track_vecs,
- "mapbar",
- "Mapbar (China) navigation track for Sonim Xp3300",
- "trk",
- nullptr,
- },
- {
- &f90g_track_vecs,
- "f90g",
- "F90G Automobile DVR GPS log file",
- "map",
- nullptr,
- },
- {
- &mapfactor_vecs,
- "mapfactor",
- "Mapfactor Navigator",
- "xml",
- nullptr,
- },
- {
- &energympro_vecs,
- "energympro",
- "Energympro GPS training watch",
- "cpo",
- nullptr,
- },
- {
- &mynav_vecs,
- "mynav",
- "MyNav TRC format",
- "trc",
- nullptr,
- },
- {
- &geojson_vecs,
- "geojson",
- "GeoJson",
- "json",
- nullptr,
- },
- {
- &ggv_bin_vecs,
- "ggv_bin",
- "Geogrid-Viewer binary overlay file (.ovl)",
- "ovl",
- nullptr,
- },
- {
- &globalsat_sport_vecs,
- "globalsat",
- "GlobalSat GH625XT GPS training watch",
- nullptr,
- nullptr,
- }
-#endif // MAXIMAL_ENABLED
-};
-
/*
* When we modify an element on the list we need to be careful
* that we are not modifying a Qt COW copy.
* Qt has an undocumented but public member function isDetached().
* If the list is detached it implies it is not shared, then functions
- * then might detach, like the iterator begin which is implcitly used
+ * then might detach, like the iterator begin which is implicitly used
* in the range based for loop, won't cause a copy to be created.
* We can make sure this is true for at least our regression cases
* with assertions.
* There is an odd situation that an empty QVector is not detached,
* so we have to exclude this from the check.
- * The possibility of detachement is also why the type of element
+ * The possibility of detachment is also why the type of element
* on the list must be default constructable. This is why we have
* to supply a default for any const members of arglist_t. Without
* the default the default constructor would be implicitly deleted.
*/
-void
-init_vecs()
+void Vecs::init_vecs()
{
for (const auto& vec : vec_list) {
- if (vec.vec->args && !vec.vec->args->isEmpty()) {
- assert(vec.vec->args->isDetached());
- for (auto& arg : *vec.vec->args) {
+ QVector<arglist_t>* args = vec.vec->get_args();
+ if (args && !args->isEmpty()) {
+ assert(args->isDetached());
+ for (auto& arg : *args) {
arg.argvalptr = nullptr;
if (arg.argval) {
*arg.argval = nullptr;
}
}
-static int
-is_integer(const char* c)
+int Vecs::is_integer(const char* c)
{
return isdigit(c[0]) || ((c[0] == '+' || c[0] == '-') && isdigit(c[1]));
}
-void
-exit_vecs()
+void Vecs::exit_vecs()
{
for (const auto& vec : vec_list) {
- if (vec.vec->exit) {
- (*vec.vec->exit)();
- }
- if (vec.vec->args && !vec.vec->args->isEmpty()) {
- assert(vec.vec->args->isDetached());
- for (auto& arg : *vec.vec->args) {
+ (vec.vec->exit)();
+ QVector<arglist_t>* args = vec.vec->get_args();
+ if (args && !args->isEmpty()) {
+ assert(args->isDetached());
+ for (auto& arg : *args) {
if (arg.argvalptr) {
xfree(arg.argvalptr);
*arg.argval = arg.argvalptr = nullptr;
}
}
-void
-assign_option(const QString& module, arglist_t* arg, const char* val)
+void Vecs::assign_option(const QString& module, arglist_t* arg, const char* val)
{
const char* c;
*arg->argval = arg->argvalptr = xstrdup(c);
}
-void
-disp_vec_options(const QString& vecname, const QVector<arglist_t>* args)
+void Vecs::disp_vec_options(const QString& vecname, const QVector<arglist_t>* args)
{
if (args) {
for (const auto& arg : *args) {
}
}
-void validate_options(const QStringList& options, const QVector<arglist_t>* args, const QString& name)
+void Vecs::validate_options(const QStringList& options, const QVector<arglist_t>* args, const QString& name)
{
for (const auto& option : options) {
const QString option_name = option.left(option.indexOf('='));
}
}
-ff_vecs_t*
-find_vec(const QString& vecname)
+Format* Vecs::find_vec(const QString& vecname)
{
QStringList options = vecname.split(',');
if (options.isEmpty()) {
continue;
}
- validate_options(options, vec.vec->args, vec.name);
+ QVector<arglist_t>* args = vec.vec->get_args();
+
+ validate_options(options, args, vec.name);
- if (vec.vec->args && !vec.vec->args->isEmpty()) {
- assert(vec.vec->args->isDetached());
- for (auto& arg : *vec.vec->args) {
+ if (args && !args->isEmpty()) {
+ assert(args->isDetached());
+ for (auto& arg : *args) {
if (!options.isEmpty()) {
const QString opt = get_option(options, arg.argstring);
if (!opt.isNull()) {
}
if (global_opts.debug_level >= 1) {
- disp_vec_options(vec.name, vec.vec->args);
+ disp_vec_options(vec.name, args);
}
#if CSVFMTS_ENABLED
// xcsv_setup_internal_style( nullptr );
#endif // CSVFMTS_ENABLED
- vec.vec->name = vec.name; /* needed for session information */
+ vec.vec->set_name(vec.name); /* needed for session information */
return vec.vec;
}
continue;
}
- validate_options(options, vec_list.at(0).vec->args, svec.name);
+ QVector<arglist_t>* xcsv_args = vec_list.at(0).vec->get_args();
- if (vec_list[0].vec->args && !vec_list[0].vec->args->isEmpty()) {
- assert(vec_list[0].vec->args->isDetached());
- for (auto& arg : *vec_list[0].vec->args) {
+ validate_options(options, xcsv_args, svec.name);
+
+ if (xcsv_args && !xcsv_args->isEmpty()) {
+ assert(xcsv_args->isDetached());
+ for (auto& arg : *xcsv_args) {
if (!options.isEmpty()) {
const QString opt = get_option(options, arg.argstring);
if (!opt.isNull()) {
}
if (global_opts.debug_level >= 1) {
- disp_vec_options(svec.name, vec_list[0].vec->args);
+ disp_vec_options(svec.name, xcsv_args);
}
#if CSVFMTS_ENABLED
xcsv_setup_internal_style(svec.style_buf);
#endif // CSVFMTS_ENABLED
- vec_list[0].vec->name = svec.name; /* needed for session information */
+ vec_list[0].vec->set_name(svec.name); /* needed for session information */
return vec_list[0].vec;
}
* Find and return a specific argument in an arg list.
* Modelled approximately after getenv.
*/
-QString
-get_option(const QStringList& options, const char* argname)
+QString Vecs::get_option(const QStringList& options, const char* argname)
{
QString rval;
* alphabetically. Returns an allocated copy of a style_vecs_array
* that's populated and sorted.
*/
-static QVector<vecs_t>
-sort_and_unify_vecs()
+QVector<Vecs::vecs_t> Vecs::sort_and_unify_vecs() const
{
QVector<vecs_t> svp;
svp.reserve(vec_list.size() + style_list.size());
svp.append(uvec);
}
+#if CSVFMTS_ENABLED
/* The style formats are based on the xcsv format,
* Make sure we know which entry in the vector list that is.
*/
* the option to set the style file. Make sure we know which entry in
* the argument list that is.
*/
- assert(case_ignore_strcmp(vec_list.at(0).vec->args->at(0).helpstring,
+ assert(case_ignore_strcmp(vec_list.at(0).vec->get_args()->at(0).helpstring,
"Full path to XCSV style file") == 0);
/* Prepare a modified argument list for the style formats. */
- auto xcsv_args = new QVector<arglist_t>(*vec_list.at(0).vec->args); /* LEAK */
+ auto xcsv_args = new QVector<arglist_t>(*vec_list.at(0).vec->get_args()); /* LEAK */
xcsv_args->removeFirst();
/* Walk the style list, parse the entries, dummy up a "normal" vec */
vecs_t uvec;
uvec.name = svec.name;
uvec.extensions = xcsv_file.extension;
- uvec.vec = new ff_vecs_t(*vec_list.at(0).vec); /* Inherits xcsv opts */ /* LEAK */
+ /* TODO: This needs to be reworked when xcsv isn't a LegacyFormat and
+ * xcsv_vecs disappear.
+ */
+ auto ffvec = ff_vecs_t(xcsv_vecs); /* Inherits xcsv opts */
/* Reset file type to inherit ff_type from xcsv. */
- uvec.vec->type = xcsv_file.type;
+ ffvec.type = xcsv_file.type;
/* Skip over the first help entry for all but the
* actual 'xcsv' format - so we don't expose the
* 'Full path to XCSV style file' argument to any
* GUIs for an internal format.
*/
- uvec.vec->args = xcsv_args;
- memset(&uvec.vec->cap, 0, sizeof(uvec.vec->cap));
+ ffvec.args = xcsv_args;
+ ffvec.cap.fill(ff_cap_none);
switch (xcsv_file.datatype) {
case unknown_gpsdata:
case wptdata:
- uvec.vec->cap[ff_cap_rw_wpt] = (ff_cap)(ff_cap_read | ff_cap_write);
+ ffvec.cap[ff_cap_rw_wpt] = (ff_cap)(ff_cap_read | ff_cap_write);
break;
case trkdata:
- uvec.vec->cap[ff_cap_rw_trk] = (ff_cap)(ff_cap_read | ff_cap_write);
+ ffvec.cap[ff_cap_rw_trk] = (ff_cap)(ff_cap_read | ff_cap_write);
break;
case rtedata:
- uvec.vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write);
+ ffvec.cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write);
break;
default:
;
}
+ uvec.vec = new LegacyFormat(ffvec); /* LEAK */
uvec.desc = xcsv_file.description;
uvec.parent = "xcsv";
svp.append(uvec);
}
+#endif // CSVFMTS_ENABLED
/*
* Display the available formats in a format that's easy for humans to
#define VEC_FMT " %-20.20s %-.50s\n"
-void
-disp_vecs()
+void Vecs::disp_vecs() const
{
const auto svp = sort_and_unify_vecs();
for (const auto& vec : svp) {
- if (vec.vec->type == ff_type_internal) {
+ if (vec.vec->get_type() == ff_type_internal) {
continue;
}
printf(VEC_FMT, qPrintable(vec.name), qPrintable(vec.desc));
- if (vec.vec->args) {
- for (const auto& arg : qAsConst(*vec.vec->args)) {
+ const QVector<arglist_t>* args = vec.vec->get_args();
+ if (args) {
+ for (const auto& arg : *args) {
if (!(arg.argtype & ARGTYPE_HIDDEN))
printf(" %-18.18s %s%-.50s %s\n",
arg.argstring,
}
}
-void
-disp_vec(const QString& vecname)
+void Vecs::disp_vec(const QString& vecname) const
{
const auto svp = sort_and_unify_vecs();
for (const auto& vec : svp) {
}
printf(VEC_FMT, qPrintable(vec.name), qPrintable(vec.desc));
- if (vec.vec->args) {
- for (const auto& arg : qAsConst(*vec.vec->args)) {
+ const QVector<arglist_t>* args = vec.vec->get_args();
+ if (args) {
+ for (const auto& arg : *args) {
if (!(arg.argtype & ARGTYPE_HIDDEN))
printf(" %-18.18s %s%-.50s %s\n",
arg.argstring,
* Additional information for V1.
* Output format type at front of line.
*/
-static void
-disp_v1(ff_type t)
+void Vecs::disp_v1(ff_type t)
{
const char* tstring;
printf("%s\t", tstring);
}
-static void
-disp_v2(const ff_vecs_t* v)
+void Vecs::disp_v2(const Format* v)
{
- for (auto& i : v->cap) {
+ for (auto& i : v->get_cap()) {
putchar((i & ff_cap_read) ? 'r' : '-');
putchar((i & ff_cap_write) ? 'w' : '-');
}
putchar('\t');
}
-const char*
-name_option(uint32_t type)
+const char* Vecs::name_option(uint32_t type)
{
const char* at[] = {
"unknown",
return at[0];
}
-static
-void disp_help_url(const vecs_t& vec, const arglist_t* arg)
+void Vecs::disp_help_url(const vecs_t& vec, const arglist_t* arg)
{
printf("\t" WEB_DOC_DIR "/fmt_%s.html", CSTR(vec.name));
if (arg) {
}
-static void
-disp_v3(const vecs_t& vec)
+void Vecs::disp_v3(const Vecs::vecs_t& vec)
{
disp_help_url(vec, nullptr);
- if (vec.vec->args) {
- for (const auto& arg : qAsConst(*vec.vec->args)) {
+ const QVector<arglist_t>* args = vec.vec->get_args();
+ if (args) {
+ for (const auto& arg : *args) {
if (!(arg.argtype & ARGTYPE_HIDDEN)) {
printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
CSTR(vec.name),
* parse. Typically invoked by programs like graphical wrappers to
* determine what formats are supported.
*/
-void
-disp_formats(int version)
+void Vecs::disp_formats(int version) const
{
const auto svp = sort_and_unify_vecs();
switch (version) {
* Version 0 skips internal types.
*/
if (version > 0) {
- disp_v1(vec.vec->type);
+ disp_v1(vec.vec->get_type());
} else {
- if (vec.vec->type == ff_type_internal) {
+ if (vec.vec->get_type() == ff_type_internal) {
continue;
}
}
//#define FIND_ALL_NULLPTR_ARGUMENTS
//#define FIND_ALL_EMPTY_ARGUMENT_LISTS
-bool validate_args(const QString& name, const QVector<arglist_t>* args)
+bool Vecs::validate_args(const QString& name, const QVector<arglist_t>* args)
{
bool ok = true;
return ok;
}
-static bool
-validate_vec(const vecs_t& vec)
+bool Vecs::validate_vec(const Vecs::vecs_t& vec)
{
- bool ok = validate_args(vec.name, vec.vec->args);
-
- if (!((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_write)) {
- if (vec.vec->wr_init != nullptr) {
- Warning() << "ERROR no write capability but non-null wr_init %s\n" << vec.name;
- ok = false;
- }
- }
- if (!((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_read)) {
- if (vec.vec->rd_init != nullptr) {
- Warning() << "ERROR no read capability but non-null rd_init %s\n" << vec.name;
- ok = false;
- }
- }
- if ((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_write) {
- if (vec.vec->wr_init == nullptr) {
- Warning() << "ERROR write capability but null wr_init %s\n" << vec.name;
- ok = false;
- }
- }
- if ((vec.vec->cap[0]|vec.vec->cap[1]|vec.vec->cap[2]) & ff_cap_read) {
- if (vec.vec->rd_init == nullptr) {
- Warning() << "ERROR read capability but null rd_init %s\n" << vec.name;
- ok = false;
- }
- }
-
- if (vec.vec->wr_init != nullptr) {
- if (vec.vec->write == nullptr) {
- Warning() << "ERROR nonnull wr_init but null write %s\n" << vec.name;
- ok = false;
- }
- if (vec.vec->wr_deinit == nullptr) {
- Warning() << "ERROR nonnull wr_init but null wr_deinit %s\n" << vec.name;
- ok = false;
- }
- }
- if (vec.vec->wr_init == nullptr) {
- if (vec.vec->write != nullptr) {
- Warning() << "ERROR null wr_init with non-null write %s\n" << vec.name;
- ok = false;
- }
- if (vec.vec->wr_deinit != nullptr) {
- Warning() << "ERROR null wr_init with non-null wr_deinit %s\n" << vec.name;
- ok = false;
- }
- }
-
- if (vec.vec->rd_init != nullptr) {
- if (vec.vec->read == nullptr) {
- Warning() << "ERROR nonnull rd_init but null read %s\n" << vec.name;
- ok = false;
- }
- if (vec.vec->rd_deinit == nullptr) {
- Warning() << "ERROR nonnull rd_init but null rd_deinit %s\n" << vec.name;
- ok = false;
- }
- }
- if (vec.vec->rd_init == nullptr) {
- if (vec.vec->read != nullptr) {
- Warning() << "ERROR null rd_init with non-null read %s\n" << vec.name;
- ok = false;
- }
- if (vec.vec->rd_deinit != nullptr) {
- Warning() << "ERROR null rd_init with non-null rd_deinit %s\n" << vec.name;
- ok = false;
- }
- }
+ bool ok = validate_args(vec.name, vec.vec->get_args());
return ok;
}
-bool validate_formats()
+bool Vecs::validate_formats() const
{
bool ok = true;
--- /dev/null
+/*
+ Describe vectors containing file operations.
+
+ Copyright (C) 2002, 2004, 2005, 2006, 2007 Robert Lipe, robertlipe+source@gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+#ifndef VECS_H_INCLUDED_
+#define VECS_H_INCLUDED_
+
+#include <cstdint>
+
+#include <QtCore/QString> // for QString
+#include <QtCore/QVector> // for QVector<>::iterator, QVector
+
+#include "defs.h"
+#include "format.h"
+#include "gpx.h"
+#include "legacyformat.h"
+
+
+#if CSVFMTS_ENABLED
+extern ff_vecs_t xcsv_vecs;
+#endif // CSVFMTS_ENABLED
+extern ff_vecs_t geo_vecs;
+extern ff_vecs_t mag_svecs;
+extern ff_vecs_t mag_fvecs;
+extern ff_vecs_t magX_fvecs;
+extern ff_vecs_t garmin_vecs;
+extern ff_vecs_t gdb_vecs;
+extern ff_vecs_t mapsend_vecs;
+extern ff_vecs_t mps_vecs;
+extern ff_vecs_t nmea_vecs;
+extern ff_vecs_t ozi_vecs;
+extern ff_vecs_t pcx_vecs;
+extern ff_vecs_t kml_vecs;
+#if MAXIMAL_ENABLED
+extern ff_vecs_t gpsutil_vecs;
+extern ff_vecs_t lowranceusr_vecs;
+extern ff_vecs_t holux_vecs;
+extern ff_vecs_t tpg_vecs;
+extern ff_vecs_t tpo2_vecs;
+extern ff_vecs_t tpo3_vecs;
+extern ff_vecs_t tmpro_vecs;
+extern ff_vecs_t tiger_vecs;
+extern ff_vecs_t easygps_vecs;
+extern ff_vecs_t saroute_vecs;
+extern ff_vecs_t navicache_vecs;
+extern ff_vecs_t psit_vecs;
+#if SHAPELIB_ENABLED
+extern ff_vecs_t shape_vecs;
+#endif
+extern ff_vecs_t gpl_vecs;
+extern ff_vecs_t text_vecs;
+extern ff_vecs_t html_vecs;
+extern ff_vecs_t netstumbler_vecs;
+extern ff_vecs_t igc_vecs;
+extern ff_vecs_t brauniger_iq_vecs;
+extern ff_vecs_t mtk_vecs;
+extern ff_vecs_t mtk_fvecs;
+extern ff_vecs_t mtk_m241_vecs;
+extern ff_vecs_t mtk_m241_fvecs;
+extern ff_vecs_t mtk_locus_vecs;
+#endif // MAXIMAL_ENABLED
+extern ff_vecs_t wbt_svecs;
+#if MAXIMAL_ENABLED
+extern ff_vecs_t vpl_vecs;
+extern ff_vecs_t wbt_fvecs;
+//extern ff_vecs_t wbt_fvecs;
+extern ff_vecs_t hiketech_vecs;
+extern ff_vecs_t glogbook_vecs;
+extern ff_vecs_t vcf_vecs;
+extern ff_vecs_t google_dir_vecs;
+extern ff_vecs_t maggeo_vecs;
+extern ff_vecs_t an1_vecs;
+extern ff_vecs_t tomtom_vecs;
+extern ff_vecs_t tef_xml_vecs;
+extern ff_vecs_t vitosmt_vecs;
+extern ff_vecs_t wfff_xml_vecs;
+extern ff_vecs_t bcr_vecs;
+extern ff_vecs_t ignr_vecs;
+#if CSVFMTS_ENABLED
+extern ff_vecs_t stmsdf_vecs;
+#endif // CSVFMTS_ENABLED
+#if CSVFMTS_ENABLED
+extern ff_vecs_t stmwpp_vecs;
+#endif // CSVFMTS_ENABLED
+extern ff_vecs_t cst_vecs;
+extern ff_vecs_t nmn4_vecs;
+#if CSVFMTS_ENABLED
+extern ff_vecs_t compegps_vecs;
+#endif // CSVFMTS_ENABLED
+extern ff_vecs_t yahoo_vecs;
+extern ff_vecs_t unicsv_vecs;
+extern ff_vecs_t gtm_vecs;
+extern ff_vecs_t gpssim_vecs;
+#if CSVFMTS_ENABLED
+extern ff_vecs_t garmin_txt_vecs;
+#endif // CSVFMTS_ENABLED
+extern ff_vecs_t gtc_vecs;
+extern ff_vecs_t dmtlog_vecs;
+extern ff_vecs_t raymarine_vecs;
+extern ff_vecs_t alanwpr_vecs;
+extern ff_vecs_t alantrl_vecs;
+extern ff_vecs_t vitovtt_vecs;
+extern ff_vecs_t ggv_log_vecs;
+#if CSVFMTS_ENABLED
+extern ff_vecs_t g7towin_vecs;
+#endif // CSVFMTS_ENABLED
+extern ff_vecs_t garmin_gpi_vecs;
+extern ff_vecs_t lmx_vecs;
+extern ff_vecs_t random_vecs;
+extern ff_vecs_t xol_vecs;
+extern ff_vecs_t dg100_vecs;
+extern ff_vecs_t dg200_vecs;
+extern ff_vecs_t navilink_vecs;
+extern ff_vecs_t ik3d_vecs;
+extern ff_vecs_t osm_vecs;
+extern ff_vecs_t destinator_poi_vecs;
+extern ff_vecs_t destinator_itn_vecs;
+extern ff_vecs_t destinator_trl_vecs;
+extern ff_vecs_t exif_vecs;
+extern ff_vecs_t vidaone_vecs;
+extern ff_vecs_t igo8_vecs;
+extern ff_vecs_t gopal_vecs;
+extern ff_vecs_t humminbird_vecs;
+extern ff_vecs_t humminbird_ht_vecs;
+extern ff_vecs_t mapasia_tr7_vecs;
+extern ff_vecs_t gnav_trl_vecs;
+extern ff_vecs_t navitel_trk_vecs;
+extern ff_vecs_t ggv_ovl_vecs;
+#if CSVFMTS_ENABLED
+extern ff_vecs_t jtr_vecs;
+#endif // CSVFMTS_ENABLED
+extern ff_vecs_t itracku_vecs;
+extern ff_vecs_t itracku_fvecs;
+extern ff_vecs_t sbp_vecs;
+extern ff_vecs_t sbn_vecs;
+extern ff_vecs_t mmo_vecs;
+extern ff_vecs_t bushnell_vecs;
+extern ff_vecs_t bushnell_trl_vecs;
+extern ff_vecs_t skyforce_vecs;
+extern ff_vecs_t pocketfms_bc_vecs;
+extern ff_vecs_t pocketfms_fp_vecs;
+extern ff_vecs_t pocketfms_wp_vecs;
+extern ff_vecs_t v900_vecs;
+extern ff_vecs_t ng_vecs;
+extern ff_vecs_t enigma_vecs;
+extern ff_vecs_t skytraq_vecs;
+extern ff_vecs_t teletype_vecs;
+extern ff_vecs_t skytraq_fvecs;
+extern ff_vecs_t miniHomer_vecs;
+extern ff_vecs_t jogmap_vecs;
+extern ff_vecs_t wintec_tes_vecs;
+extern ff_vecs_t subrip_vecs;
+extern ff_vecs_t format_garmin_xt_vecs;
+extern ff_vecs_t format_fit_vecs;
+extern ff_vecs_t mapbar_track_vecs;
+extern ff_vecs_t f90g_track_vecs;
+extern ff_vecs_t mapfactor_vecs;
+extern ff_vecs_t energympro_vecs;
+extern ff_vecs_t mynav_vecs;
+extern ff_vecs_t geojson_vecs;
+extern ff_vecs_t ggv_bin_vecs;
+extern ff_vecs_t globalsat_sport_vecs;
+#endif // MAXIMAL_ENABLED
+
+class Vecs
+{
+// Meyers Singleton
+public:
+ static Vecs& Instance()
+ {
+ static Vecs instance;
+ return instance;
+ }
+ Vecs(const Vecs&) = delete;
+ Vecs& operator= (const Vecs&) = delete;
+ Vecs(Vecs&&) = delete;
+ Vecs& operator=(Vecs&&) = delete;
+
+private:
+ Vecs() = default;
+ ~Vecs() = default;
+
+private:
+ struct vecs_t {
+ Format* vec;
+ QString name;
+ QString desc;
+ QString extensions; // list of possible extensions separated by '/', first is output default for GUI.
+ QString parent;
+ };
+
+public:
+ void init_vecs();
+ void exit_vecs();
+ static void assign_option(const QString& module, arglist_t* arg, const char* val);
+ static void disp_vec_options(const QString& vecname, const QVector<arglist_t>* args);
+ static void validate_options(const QStringList& options, const QVector<arglist_t>* args, const QString& name);
+ static QString get_option(const QStringList& options, const char* argname);
+ Format* find_vec(const QString& vecname);
+ void disp_vecs() const;
+ void disp_vec(const QString& vecname) const;
+ static const char* name_option(uint32_t type);
+ void disp_formats(int version) const;
+ static bool validate_args(const QString& name, const QVector<arglist_t>* args);
+ bool validate_formats() const;
+
+private:
+ static int is_integer(const char* c);
+ QVector<vecs_t> sort_and_unify_vecs() const;
+ static void disp_v1(ff_type t);
+ static void disp_v2(const Format* v);
+ static void disp_help_url(const vecs_t& vec, const arglist_t* arg);
+ static void disp_v3(const vecs_t& vec);
+ static bool validate_vec(const vecs_t& vec);
+
+private:
+ /*
+ * Having these LegacyFormat instances be non-static data members
+ * prevents the static initialization order fiasco because
+ * the static vec that is used to construct a legacy format
+ * instance is guaranteed to have already constructed when an instance
+ * of this class is constructed.
+ */
+#if CSVFMTS_ENABLED
+ LegacyFormat xcsv_fmt {xcsv_vecs};
+#endif // CSVFMTS_ENABLED
+ LegacyFormat geo_fmt {geo_vecs};
+ GpxFormat gpx_fmt;
+ LegacyFormat mag_sfmt {mag_svecs};
+ LegacyFormat mag_ffmt {mag_fvecs};
+ LegacyFormat magX_ffmt {magX_fvecs};
+ LegacyFormat garmin_fmt {garmin_vecs};
+ LegacyFormat gdb_fmt {gdb_vecs};
+ LegacyFormat mapsend_fmt {mapsend_vecs};
+ LegacyFormat mps_fmt {mps_vecs};
+ LegacyFormat nmea_fmt {nmea_vecs};
+ LegacyFormat ozi_fmt {ozi_vecs};
+ LegacyFormat pcx_fmt {pcx_vecs};
+ LegacyFormat kml_fmt {kml_vecs};
+#if MAXIMAL_ENABLED
+ LegacyFormat gpsutil_fmt {gpsutil_vecs};
+ LegacyFormat lowranceusr_fmt {lowranceusr_vecs};
+ LegacyFormat holux_fmt {holux_vecs};
+ LegacyFormat tpg_fmt {tpg_vecs};
+ LegacyFormat tpo2_fmt {tpo2_vecs};
+ LegacyFormat tpo3_fmt {tpo3_vecs};
+ LegacyFormat tmpro_fmt {tmpro_vecs};
+ LegacyFormat tiger_fmt {tiger_vecs};
+ LegacyFormat easygps_fmt {easygps_vecs};
+ LegacyFormat saroute_fmt {saroute_vecs};
+ LegacyFormat navicache_fmt {navicache_vecs};
+ LegacyFormat psit_fmt {psit_vecs};
+#if SHAPELIB_ENABLED
+ LegacyFormat shape_fmt {shape_vecs};
+#endif
+ LegacyFormat gpl_fmt {gpl_vecs};
+ LegacyFormat text_fmt {text_vecs};
+ LegacyFormat html_fmt {html_vecs};
+ LegacyFormat netstumbler_fmt {netstumbler_vecs};
+ LegacyFormat igc_fmt {igc_vecs};
+ LegacyFormat brauniger_iq_fmt {brauniger_iq_vecs};
+ LegacyFormat mtk_fmt {mtk_vecs};
+ LegacyFormat mtk_ffmt {mtk_fvecs};
+ LegacyFormat mtk_m241_fmt {mtk_m241_vecs};
+ LegacyFormat mtk_m241_ffmt {mtk_m241_fvecs};
+ LegacyFormat mtk_locus_fmt {mtk_locus_vecs};
+#endif // MAXIMAL_ENABLED
+ LegacyFormat wbt_sfmt {wbt_svecs};
+#if MAXIMAL_ENABLED
+ LegacyFormat vpl_fmt {vpl_vecs};
+ LegacyFormat wbt_ffmt {wbt_fvecs};
+//LegacyFormat wbt_ffmt {wbt_fvecs};
+ LegacyFormat hiketech_fmt {hiketech_vecs};
+ LegacyFormat glogbook_fmt {glogbook_vecs};
+ LegacyFormat vcf_fmt {vcf_vecs};
+ LegacyFormat google_dir_fmt {google_dir_vecs};
+ LegacyFormat maggeo_fmt {maggeo_vecs};
+ LegacyFormat an1_fmt {an1_vecs};
+ LegacyFormat tomtom_fmt {tomtom_vecs};
+ LegacyFormat tef_xml_fmt {tef_xml_vecs};
+ LegacyFormat vitosmt_fmt {vitosmt_vecs};
+ LegacyFormat wfff_xml_fmt {wfff_xml_vecs};
+ LegacyFormat bcr_fmt {bcr_vecs};
+ LegacyFormat ignr_fmt {ignr_vecs};
+#if CSVFMTS_ENABLED
+ LegacyFormat stmsdf_fmt {stmsdf_vecs};
+#endif // CSVFMTS_ENABLED
+#if CSVFMTS_ENABLED
+ LegacyFormat stmwpp_fmt {stmwpp_vecs};
+#endif // CSVFMTS_ENABLED
+ LegacyFormat cst_fmt {cst_vecs};
+ LegacyFormat nmn4_fmt {nmn4_vecs};
+#if CSVFMTS_ENABLED
+ LegacyFormat compegps_fmt {compegps_vecs};
+#endif // CSVFMTS_ENABLED
+ LegacyFormat yahoo_fmt {yahoo_vecs};
+ LegacyFormat unicsv_fmt {unicsv_vecs};
+ LegacyFormat gtm_fmt {gtm_vecs};
+ LegacyFormat gpssim_fmt {gpssim_vecs};
+#if CSVFMTS_ENABLED
+ LegacyFormat garmin_txt_fmt {garmin_txt_vecs};
+#endif // CSVFMTS_ENABLED
+ LegacyFormat gtc_fmt {gtc_vecs};
+ LegacyFormat dmtlog_fmt {dmtlog_vecs};
+ LegacyFormat raymarine_fmt {raymarine_vecs};
+ LegacyFormat alanwpr_fmt {alanwpr_vecs};
+ LegacyFormat alantrl_fmt {alantrl_vecs};
+ LegacyFormat vitovtt_fmt {vitovtt_vecs};
+ LegacyFormat ggv_log_fmt {ggv_log_vecs};
+#if CSVFMTS_ENABLED
+ LegacyFormat g7towin_fmt {g7towin_vecs};
+#endif // CSVFMTS_ENABLED
+ LegacyFormat garmin_gpi_fmt {garmin_gpi_vecs};
+ LegacyFormat lmx_fmt {lmx_vecs};
+ LegacyFormat random_fmt {random_vecs};
+ LegacyFormat xol_fmt {xol_vecs};
+ LegacyFormat dg100_fmt {dg100_vecs};
+ LegacyFormat dg200_fmt {dg200_vecs};
+ LegacyFormat navilink_fmt {navilink_vecs};
+ LegacyFormat ik3d_fmt {ik3d_vecs};
+ LegacyFormat osm_fmt {osm_vecs};
+ LegacyFormat destinator_poi_fmt {destinator_poi_vecs};
+ LegacyFormat destinator_itn_fmt {destinator_itn_vecs};
+ LegacyFormat destinator_trl_fmt {destinator_trl_vecs};
+ LegacyFormat exif_fmt {exif_vecs};
+ LegacyFormat vidaone_fmt {vidaone_vecs};
+ LegacyFormat igo8_fmt {igo8_vecs};
+ LegacyFormat gopal_fmt {gopal_vecs};
+ LegacyFormat humminbird_fmt {humminbird_vecs};
+ LegacyFormat humminbird_ht_fmt {humminbird_ht_vecs};
+ LegacyFormat mapasia_tr7_fmt {mapasia_tr7_vecs};
+ LegacyFormat gnav_trl_fmt {gnav_trl_vecs};
+ LegacyFormat navitel_trk_fmt {navitel_trk_vecs};
+ LegacyFormat ggv_ovl_fmt {ggv_ovl_vecs};
+#if CSVFMTS_ENABLED
+ LegacyFormat jtr_fmt {jtr_vecs};
+#endif // CSVFMTS_ENABLED
+ LegacyFormat itracku_fmt {itracku_vecs};
+ LegacyFormat itracku_ffmt {itracku_fvecs};
+ LegacyFormat sbp_fmt {sbp_vecs};
+ LegacyFormat sbn_fmt {sbn_vecs};
+ LegacyFormat mmo_fmt {mmo_vecs};
+ LegacyFormat bushnell_fmt {bushnell_vecs};
+ LegacyFormat bushnell_trl_fmt {bushnell_trl_vecs};
+ LegacyFormat skyforce_fmt {skyforce_vecs};
+ LegacyFormat pocketfms_bc_fmt {pocketfms_bc_vecs};
+ LegacyFormat pocketfms_fp_fmt {pocketfms_fp_vecs};
+ LegacyFormat pocketfms_wp_fmt {pocketfms_wp_vecs};
+ LegacyFormat v900_fmt {v900_vecs};
+ LegacyFormat ng_fmt {ng_vecs};
+ LegacyFormat enigma_fmt {enigma_vecs};
+ LegacyFormat skytraq_fmt {skytraq_vecs};
+ LegacyFormat teletype_fmt {teletype_vecs};
+ LegacyFormat skytraq_ffmt {skytraq_fvecs};
+ LegacyFormat miniHomer_fmt {miniHomer_vecs};
+ LegacyFormat jogmap_fmt {jogmap_vecs};
+ LegacyFormat wintec_tes_fmt {wintec_tes_vecs};
+ LegacyFormat subrip_fmt {subrip_vecs};
+ LegacyFormat format_garmin_xt_fmt {format_garmin_xt_vecs};
+ LegacyFormat format_fit_fmt {format_fit_vecs};
+ LegacyFormat mapbar_track_fmt {mapbar_track_vecs};
+ LegacyFormat f90g_track_fmt {f90g_track_vecs};
+ LegacyFormat mapfactor_fmt {mapfactor_vecs};
+ LegacyFormat energympro_fmt {energympro_vecs};
+ LegacyFormat mynav_fmt {mynav_vecs};
+ LegacyFormat geojson_fmt {geojson_vecs};
+ LegacyFormat ggv_bin_fmt {ggv_bin_vecs};
+ LegacyFormat globalsat_sport_fmt {globalsat_sport_vecs};
+#endif // MAXIMAL_ENABLED
+
+ const QVector<vecs_t> vec_list {
+#if CSVFMTS_ENABLED
+ /* XCSV must be the first entry in this table. */
+ {
+ &xcsv_fmt,
+ "xcsv",
+ "? Character Separated Values",
+ nullptr,
+ nullptr,
+ },
+#endif
+ {
+ &geo_fmt,
+ "geo",
+ "Geocaching.com .loc",
+ "loc",
+ nullptr,
+ },
+ {
+ &gpx_fmt,
+ "gpx",
+ "GPX XML",
+ "gpx",
+ nullptr,
+ },
+ {
+ &mag_sfmt,
+ "magellan",
+ "Magellan serial protocol",
+ nullptr,
+ nullptr,
+ },
+ {
+ &mag_ffmt,
+ "magellan",
+ "Magellan SD files (as for Meridian)",
+ nullptr,
+ nullptr,
+ },
+ {
+ &magX_ffmt,
+ "magellanx",
+ "Magellan SD files (as for eXplorist)",
+ "upt",
+ nullptr,
+ },
+ {
+ &garmin_fmt,
+ "garmin",
+ "Garmin serial/USB protocol",
+ nullptr,
+ nullptr,
+ },
+ {
+ &gdb_fmt,
+ "gdb",
+ "Garmin MapSource - gdb",
+ "gdb",
+ nullptr,
+ },
+ {
+ &mapsend_fmt,
+ "mapsend",
+ "Magellan Mapsend",
+ nullptr,
+ nullptr,
+ },
+ {
+ &mps_fmt,
+ "mapsource",
+ "Garmin MapSource - mps",
+ "mps",
+ nullptr,
+ },
+ {
+ &nmea_fmt,
+ "nmea",
+ "NMEA 0183 sentences",
+ nullptr,
+ nullptr,
+ },
+ {
+ &ozi_fmt,
+ "ozi",
+ "OziExplorer",
+ nullptr,
+ nullptr,
+ },
+ {
+ &pcx_fmt,
+ "pcx",
+ "Garmin PCX5",
+ "pcx",
+ nullptr,
+ },
+ {
+ &kml_fmt,
+ "kml",
+ "Google Earth (Keyhole) Markup Language",
+ "kml",
+ nullptr,
+ },
+#if MAXIMAL_ENABLED
+ {
+ &gpsutil_fmt,
+ "gpsutil",
+ "gpsutil",
+ nullptr,
+ nullptr,
+ },
+ {
+ &lowranceusr_fmt,
+ "lowranceusr",
+ "Lowrance USR",
+ "usr",
+ nullptr,
+ },
+ {
+ &holux_fmt,
+ "holux",
+ "Holux (gm-100) .wpo Format",
+ "wpo",
+ nullptr,
+ },
+ {
+ &tpg_fmt,
+ "tpg",
+ "National Geographic Topo .tpg (waypoints)",
+ "tpg",
+ nullptr,
+ },
+ {
+ &tpo2_fmt,
+ "tpo2",
+ "National Geographic Topo 2.x .tpo",
+ "tpo",
+ nullptr,
+ },
+ {
+ &tpo3_fmt,
+ "tpo3",
+ "National Geographic Topo 3.x/4.x .tpo",
+ "tpo",
+ nullptr,
+ },
+ {
+ &tmpro_fmt,
+ "tmpro",
+ "TopoMapPro Places File",
+ "tmpro",
+ nullptr,
+ },
+ {
+ &tiger_fmt,
+ "tiger",
+ "U.S. Census Bureau Tiger Mapping Service",
+ nullptr,
+ nullptr,
+ },
+ {
+ &easygps_fmt,
+ "easygps",
+ "EasyGPS binary format",
+ "loc",
+ nullptr,
+ },
+ {
+ &saroute_fmt,
+ "saroute",
+ "DeLorme Street Atlas Route",
+ "anr",
+ nullptr,
+ },
+ {
+ &navicache_fmt,
+ "navicache",
+ "Navicache.com XML",
+ nullptr,
+ nullptr,
+ },
+ { /* MRCB */
+ &psit_fmt,
+ "psitrex",
+ "KuDaTa PsiTrex text",
+ nullptr,
+ nullptr,
+ },
+#if SHAPELIB_ENABLED
+ {
+ &shape_fmt,
+ "shape",
+ "ESRI shapefile",
+ "shp",
+ nullptr,
+ },
+#endif
+ {
+ &gpl_fmt,
+ "gpl",
+ "DeLorme GPL",
+ "gpl",
+ nullptr,
+ },
+ {
+ &text_fmt,
+ "text",
+ "Textual Output",
+ "txt",
+ nullptr,
+ },
+ {
+ &html_fmt,
+ "html",
+ "HTML Output",
+ "html",
+ nullptr,
+ },
+ {
+ &netstumbler_fmt,
+ "netstumbler",
+ "NetStumbler Summary File (text)",
+ nullptr,
+ nullptr,
+ },
+ {
+ &igc_fmt,
+ "igc",
+ "FAI/IGC Flight Recorder Data Format",
+ nullptr,
+ nullptr,
+ },
+ {
+ &brauniger_iq_fmt,
+ "baroiq",
+ "Brauniger IQ Series Barograph Download",
+ nullptr,
+ nullptr,
+ },
+ {
+ &mtk_fmt,
+ "mtk",
+ "MTK Logger (iBlue 747,Qstarz BT-1000,...) download",
+ nullptr,
+ nullptr,
+ },
+ {
+ &mtk_ffmt,
+ "mtk-bin",
+ "MTK Logger (iBlue 747,...) Binary File Format",
+ "bin",
+ nullptr,
+ },
+ {
+ &mtk_m241_fmt,
+ "m241",
+ "Holux M-241 (MTK based) download",
+ nullptr,
+ nullptr,
+ },
+ {
+ &mtk_m241_ffmt,
+ "m241-bin",
+ "Holux M-241 (MTK based) Binary File Format",
+ "bin",
+ nullptr,
+ },
+ {
+ &mtk_locus_fmt,
+ "mtk_locus",
+ "MediaTek Locus",
+ nullptr,
+ nullptr,
+ },
+#endif // MAXIMAL_ENABLED
+ {
+ &wbt_sfmt,
+ "wbt",
+ "Wintec WBT-100/200 GPS Download",
+ nullptr,
+ nullptr,
+ },
+#if MAXIMAL_ENABLED
+ {
+ &vpl_fmt,
+ "vpl",
+ "Honda/Acura Navigation System VP Log File Format",
+ nullptr,
+ nullptr,
+ },
+ {
+ &wbt_ffmt,
+ "wbt-bin",
+ "Wintec WBT-100/200 Binary File Format",
+ "bin",
+ nullptr,
+ },
+ {
+ &wbt_ffmt,
+ "wbt-tk1",
+ "Wintec WBT-201/G-Rays 2 Binary File Format",
+ "tk1",
+ nullptr,
+ },
+ {
+ &hiketech_fmt,
+ "hiketech",
+ "HikeTech",
+ "gps",
+ nullptr,
+ },
+ {
+ &glogbook_fmt,
+ "glogbook",
+ "Garmin Logbook XML",
+ "xml",
+ nullptr,
+ },
+ {
+ &vcf_fmt,
+ "vcard",
+ "Vcard Output (for iPod)",
+ "vcf",
+ nullptr,
+ },
+ {
+ &google_dir_fmt,
+ "googledir",
+ "Google Directions XML",
+ "xml",
+ nullptr,
+ },
+ {
+ &maggeo_fmt,
+ "maggeo",
+ "Magellan Explorist Geocaching",
+ "gs",
+ nullptr,
+ },
+ {
+ &an1_fmt,
+ "an1",
+ "DeLorme .an1 (drawing) file",
+ "an1",
+ nullptr,
+ },
+ {
+ &tomtom_fmt,
+ "tomtom",
+ "TomTom POI file (.ov2)",
+ "ov2",
+ nullptr,
+ },
+ {
+ &tef_xml_fmt,
+ "tef",
+ "Map&Guide 'TourExchangeFormat' XML",
+ "xml",
+ nullptr,
+ },
+ {
+ &vitosmt_fmt,
+ "vitosmt",
+ "Vito Navigator II tracks",
+ "smt",
+ nullptr,
+ },
+ {
+ &wfff_xml_fmt,
+ "wfff",
+ "WiFiFoFum 2.0 for PocketPC XML",
+ "xml",
+ nullptr,
+ },
+ {
+ &bcr_fmt,
+ "bcr",
+ "Motorrad Routenplaner (Map&Guide) .bcr files",
+ "bcr",
+ nullptr,
+ },
+ {
+ &ignr_fmt,
+ "ignrando",
+ "IGN Rando track files",
+ "rdn",
+ nullptr,
+ },
+#if CSVFMTS_ENABLED
+ {
+ &stmsdf_fmt,
+ "stmsdf",
+ "Suunto Trek Manager (STM) .sdf files",
+ "sdf",
+ nullptr,
+ },
+#endif
+#if CSVFMTS_ENABLED
+ {
+ &stmwpp_fmt,
+ "stmwpp",
+ "Suunto Trek Manager (STM) WaypointPlus files",
+ "txt",
+ nullptr,
+ },
+#endif // CSVFMTS_ENABLED
+ {
+ &cst_fmt,
+ "cst",
+ "CarteSurTable data file",
+ "cst",
+ nullptr,
+ },
+ {
+ &nmn4_fmt,
+ "nmn4",
+ "Navigon Mobile Navigator .rte files",
+ "rte",
+ nullptr,
+ },
+#if CSVFMTS_ENABLED
+ {
+ &compegps_fmt,
+ "compegps",
+ "CompeGPS data files (.wpt/.trk/.rte)",
+ nullptr,
+ nullptr,
+ },
+#endif //CSVFMTS_ENABLED
+ {
+ &yahoo_fmt,
+ "yahoo",
+ "Yahoo Geocode API data",
+ nullptr,
+ nullptr,
+ },
+ {
+ &unicsv_fmt,
+ "unicsv",
+ "Universal csv with field structure in first line",
+ nullptr,
+ nullptr,
+ },
+ {
+ >m_fmt,
+ "gtm",
+ "GPS TrackMaker",
+ "gtm",
+ nullptr,
+ },
+ {
+ &gpssim_fmt,
+ "gpssim",
+ "Franson GPSGate Simulation",
+ "gpssim",
+ nullptr,
+ },
+#if CSVFMTS_ENABLED
+ {
+ &garmin_txt_fmt,
+ "garmin_txt",
+ "Garmin MapSource - txt (tab delimited)",
+ "txt",
+ nullptr,
+ },
+#endif // CSVFMTS_ENABLED
+ {
+ >c_fmt,
+ "gtrnctr",
+ "Garmin Training Center (.tcx/.crs/.hst/.xml)",
+ "tcx/crs/hst/xml",
+ nullptr,
+ },
+ {
+ &dmtlog_fmt,
+ "dmtlog",
+ "TrackLogs digital mapping (.trl)",
+ "trl",
+ nullptr,
+ },
+ {
+ &raymarine_fmt,
+ "raymarine",
+ "Raymarine Waypoint File (.rwf)",
+ "rwf",
+ nullptr,
+ },
+ {
+ &alanwpr_fmt,
+ "alanwpr",
+ "Alan Map500 waypoints and routes (.wpr)",
+ "wpr",
+ nullptr,
+ },
+ {
+ &alantrl_fmt,
+ "alantrl",
+ "Alan Map500 tracklogs (.trl)",
+ "trl",
+ nullptr,
+ },
+ {
+ &vitovtt_fmt,
+ "vitovtt",
+ "Vito SmartMap tracks (.vtt)",
+ "vtt",
+ nullptr,
+ },
+ {
+ &ggv_log_fmt,
+ "ggv_log",
+ "Geogrid-Viewer tracklogs (.log)",
+ "log",
+ nullptr,
+ },
+#if CSVFMTS_ENABLED
+ {
+ &g7towin_fmt,
+ "g7towin",
+ "G7ToWin data files (.g7t)",
+ "g7t",
+ nullptr,
+ },
+#endif
+ {
+ &garmin_gpi_fmt,
+ "garmin_gpi",
+ "Garmin Points of Interest (.gpi)",
+ "gpi",
+ nullptr,
+ },
+ {
+ &lmx_fmt,
+ "lmx",
+ "Nokia Landmark Exchange",
+ nullptr,
+ nullptr,
+ },
+ {
+ &random_fmt,
+ "random",
+ "Internal GPS data generator",
+ nullptr,
+ nullptr,
+ },
+ {
+ &xol_fmt,
+ "xol",
+ "Swiss Map 25/50/100 (.xol)",
+ "xol",
+ nullptr,
+ },
+ {
+ &dg100_fmt,
+ "dg-100",
+ "GlobalSat DG-100/BT-335 Download",
+ nullptr,
+ nullptr,
+ },
+ {
+ &dg200_fmt,
+ "dg-200",
+ "GlobalSat DG-200 Download",
+ nullptr,
+ nullptr,
+ },
+ {
+ &navilink_fmt,
+ "navilink",
+ "NaviGPS GT-11/BGT-11 Download",
+ nullptr,
+ nullptr,
+ },
+ {
+ &ik3d_fmt,
+ "ik3d",
+ "MagicMaps IK3D project file (.ikt)",
+ "ikt",
+ nullptr,
+ },
+ {
+ &osm_fmt,
+ "osm",
+ "OpenStreetMap data files",
+ "osm",
+ nullptr,
+ },
+ {
+ &destinator_poi_fmt,
+ "destinator_poi",
+ "Destinator Points of Interest (.dat)",
+ "dat",
+ nullptr,
+ },
+ {
+ &destinator_itn_fmt,
+ "destinator_itn",
+ "Destinator Itineraries (.dat)",
+ "dat",
+ nullptr,
+ },
+ {
+ &destinator_trl_fmt,
+ "destinator_trl",
+ "Destinator TrackLogs (.dat)",
+ "dat",
+ nullptr,
+ },
+ {
+ &exif_fmt,
+ "exif",
+ "Embedded Exif-GPS data (.jpg)",
+ "jpg",
+ nullptr,
+ },
+ {
+ &vidaone_fmt,
+ "vidaone",
+ "VidaOne GPS for Pocket PC (.gpb)",
+ "gpb",
+ nullptr,
+ },
+ {
+ &igo8_fmt,
+ "igo8",
+ "IGO8 .trk",
+ "trk",
+ nullptr,
+ },
+ {
+ &gopal_fmt,
+ "gopal",
+ "GoPal GPS track log (.trk)",
+ "trk",
+ nullptr,
+ },
+ {
+ &humminbird_fmt,
+ "humminbird",
+ "Humminbird waypoints and routes (.hwr)",
+ "hwr",
+ nullptr,
+ },
+ {
+ &humminbird_ht_fmt,
+ "humminbird_ht",
+ "Humminbird tracks (.ht)",
+ "ht",
+ nullptr,
+ },
+ {
+ &mapasia_tr7_fmt,
+ "mapasia_tr7",
+ "MapAsia track file (.tr7)",
+ "tr7",
+ nullptr,
+ },
+ {
+ &gnav_trl_fmt,
+ "gnav_trl",
+ "Google Navigator Tracklines (.trl)",
+ "trl",
+ nullptr,
+ },
+ {
+ &navitel_trk_fmt,
+ "navitel_trk",
+ "Navitel binary track (.bin)",
+ "bin",
+ nullptr,
+ },
+ {
+ &ggv_ovl_fmt,
+ "ggv_ovl",
+ "Geogrid-Viewer ascii overlay file (.ovl)",
+ "ovl",
+ nullptr,
+ },
+#if CSVFMTS_ENABLED
+ {
+ &jtr_fmt,
+ "jtr",
+ "Jelbert GeoTagger data file",
+ "jtr",
+ nullptr,
+ },
+#endif
+ {
+ &itracku_fmt,
+ "itracku",
+ "XAiOX iTrackU Logger",
+ nullptr,
+ nullptr,
+ },
+ {
+ &itracku_ffmt,
+ "itracku-bin",
+ "XAiOX iTrackU Logger Binary File Format",
+ "bin",
+ nullptr,
+ },
+ {
+ &sbp_fmt,
+ "sbp",
+ "NaviGPS GT-31/BGT-31 datalogger (.sbp)",
+ "sbp",
+ nullptr,
+ },
+ {
+ &sbn_fmt,
+ "sbn",
+ "NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)",
+ "sbn",
+ nullptr,
+ },
+ {
+ &mmo_fmt,
+ "mmo",
+ "Memory-Map Navigator overlay files (.mmo)",
+ "mmo",
+ nullptr,
+ },
+ {
+ &bushnell_fmt,
+ "bushnell",
+ "Bushnell GPS Waypoint file",
+ "wpt",
+ nullptr,
+ },
+ {
+ &bushnell_trl_fmt,
+ "bushnell_trl",
+ "Bushnell GPS Trail file",
+ "trl",
+ nullptr,
+ },
+ {
+ &skyforce_fmt,
+ "skyforce",
+ "Skymap / KMD150 ascii files",
+ nullptr,
+ nullptr,
+ },
+ {
+ &pocketfms_bc_fmt,
+ "pocketfms_bc",
+ "PocketFMS breadcrumbs",
+ nullptr,
+ nullptr,
+ },
+ {
+ &pocketfms_fp_fmt,
+ "pocketfms_fp",
+ "PocketFMS flightplan (.xml)",
+ "xml",
+ nullptr,
+ },
+ {
+ &pocketfms_wp_fmt,
+ "pocketfms_wp",
+ "PocketFMS waypoints (.txt)",
+ "txt",
+ nullptr,
+ },
+ {
+ &v900_fmt,
+ "v900",
+ "Columbus/Visiontac V900 files (.csv)",
+ nullptr,
+ nullptr,
+ },
+ {
+ &ng_fmt,
+ "naviguide",
+ "Naviguide binary route file (.twl)",
+ "twl",
+ nullptr,
+ },
+ {
+ &enigma_fmt,
+ "enigma",
+ "Enigma binary waypoint file (.ert)",
+ "ert",
+ nullptr,
+ },
+ {
+ &skytraq_fmt,
+ "skytraq",
+ "SkyTraq Venus based loggers (download)",
+ nullptr,
+ nullptr,
+ },
+ {
+ &teletype_fmt,
+ "teletype",
+ "Teletype [ Get Jonathon Johnson to describe",
+ nullptr,
+ nullptr,
+ },
+ {
+ &skytraq_ffmt,
+ "skytraq-bin",
+ "SkyTraq Venus based loggers Binary File Format",
+ "bin",
+ nullptr,
+ },
+ {
+ &miniHomer_fmt,
+ "miniHomer",
+ "MiniHomer, a skyTraq Venus 6 based logger (download tracks, waypoints and get/set POI)",
+ nullptr,
+ nullptr,
+ },
+ {
+ &jogmap_fmt,
+ "jogmap",
+ "Jogmap.de XML format",
+ "xml",
+ nullptr,
+ },
+ {
+ &wintec_tes_fmt,
+ "wintec_tes",
+ "Wintec TES file",
+ "tes",
+ nullptr,
+ },
+ {
+ &subrip_fmt,
+ "subrip",
+ "SubRip subtitles for video mapping (.srt)",
+ "srt",
+ nullptr,
+ },
+ {
+ &format_garmin_xt_fmt,
+ "garmin_xt",
+ "Mobile Garmin XT Track files",
+ nullptr,
+ nullptr,
+ },
+ {
+ &format_fit_fmt,
+ "garmin_fit",
+ "Flexible and Interoperable Data Transfer (FIT) Activity file",
+ "fit",
+ nullptr,
+ },
+ {
+ &mapbar_track_fmt,
+ "mapbar",
+ "Mapbar (China) navigation track for Sonim Xp3300",
+ "trk",
+ nullptr,
+ },
+ {
+ &f90g_track_fmt,
+ "f90g",
+ "F90G Automobile DVR GPS log file",
+ "map",
+ nullptr,
+ },
+ {
+ &mapfactor_fmt,
+ "mapfactor",
+ "Mapfactor Navigator",
+ "xml",
+ nullptr,
+ },
+ {
+ &energympro_fmt,
+ "energympro",
+ "Energympro GPS training watch",
+ "cpo",
+ nullptr,
+ },
+ {
+ &mynav_fmt,
+ "mynav",
+ "MyNav TRC format",
+ "trc",
+ nullptr,
+ },
+ {
+ &geojson_fmt,
+ "geojson",
+ "GeoJson",
+ "json",
+ nullptr,
+ },
+ {
+ &ggv_bin_fmt,
+ "ggv_bin",
+ "Geogrid-Viewer binary overlay file (.ovl)",
+ "ovl",
+ nullptr,
+ },
+ {
+ &globalsat_sport_fmt,
+ "globalsat",
+ "GlobalSat GH625XT GPS training watch",
+ nullptr,
+ nullptr,
+ }
+#endif // MAXIMAL_ENABLED
+ };
+};
+#endif // VECS_H_INCLUDED_